■ Timeline 엘리먼트의 AccelerationRatio/DecelerationRatio 속성을 사용하는 방법을 보여준다.
▶ ElapsedTimeControl.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media.Animation; namespace TestProject { /// <summary> /// 경과 시간 컨트롤 /// </summary> public class ElapsedTimeControl : Control { //////////////////////////////////////////////////////////////////////////////////////////////////// Dependency Property ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 현재 시간 의존 속성 - CurrentTimeProperty /// <summary> /// 현재 시간 의존 속성 /// </summary> public static readonly DependencyProperty CurrentTimeProperty = DependencyProperty.Register ( "CurrentTime", typeof(TimeSpan?), typeof(ElapsedTimeControl), new FrameworkPropertyMetadata(null, CurrentTimePropertyChangedCallback) ); #endregion #region 현재 시간 문자열 의존 속성 - CurrentTimeStringProperty /// <summary> /// 현재 시간 문자열 의존 속성 /// </summary> public static readonly DependencyProperty CurrentTimeStringProperty = DependencyProperty.Register ( "CurrentTimeString", typeof(string), typeof(ElapsedTimeControl) ); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 이전 시간 범위 /// </summary> private TimeSpan? previousTimeSpan; /// <summary> /// 시계 /// </summary> private Clock clock; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 시계 - Click /// <summary> /// 시계 /// </summary> public Clock Clock { get { return this.clock; } set { if(this.clock != null) { this.clock.CurrentTimeInvalidated -= clock_CurrentTimeInvalidated; } this.clock = value; if(this.clock != null) { this.clock.CurrentTimeInvalidated += clock_CurrentTimeInvalidated; } } } #endregion #region 현재 시간 문자열 - CurrentTimeString /// <summary> /// 현재 시간 문자열 /// </summary> public string CurrentTimeString { get { return GetValue(CurrentTimeStringProperty) as string; } set { SetValue(CurrentTimeStringProperty, value); } } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - ElapsedTimeControl() /// <summary> /// 생성자 /// </summary> public ElapsedTimeControl() { } #endregion #region 생성자 - ElapsedTimeControl(previousTimeSpan) /// <summary> /// 생성자 /// </summary> /// <param name="previousTimeSpan">이전 시간 범위</param> public ElapsedTimeControl(TimeSpan? previousTimeSpan) { this.previousTimeSpan = previousTimeSpan; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 현재 시간 속성 변경시 콜백 처리하기 - CurrentTimePropertyChangedCallback(d, e) /// <summary> /// 현재 시간 속성 변경시 콜백 처리하기 /// </summary> /// <param name="d">의존 객체</param> /// <param name="e">이벤트 인자</param> private static void CurrentTimePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((ElapsedTimeControl)d).SetValue(CurrentTimeStringProperty, e.NewValue.ToString()); } #endregion #region 시계 현재 시간 무효시 처리하기 - clock_CurrentTimeInvalidated(sender, e) /// <summary> /// 시계 현재 시간 무효시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void clock_CurrentTimeInvalidated(object sender, EventArgs e) { SetValue(CurrentTimeProperty, this.clock.CurrentTime); } #endregion } } |
▶ MainWindow.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
<Window x:Class="TestProject.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:TestProject" Width="800" Height="600" Title="TestProject" FontFamily="나눔고딕코딩" FontSize="16"> <Window.Resources> <DrawingBrush x:Key="GridDrawingBrushKey" Viewport="0 0 10 10" ViewportUnits="Absolute" TileMode="Tile"> <DrawingBrush.Drawing> <DrawingGroup> <DrawingGroup.Children> <GeometryDrawing Brush="#99ffffff"> <GeometryDrawing.Geometry> <RectangleGeometry Rect="0 0 1 1" /> </GeometryDrawing.Geometry> </GeometryDrawing> <GeometryDrawing Brush="#99ccccff" Geometry="M 0 0 L 1 0 1 0.1 0 0.1 Z" /> <GeometryDrawing Brush="#99ccccff" Geometry="M 0 0 L 0 1 0.1 1 0.1 0 Z" /> </DrawingGroup.Children> </DrawingGroup> </DrawingBrush.Drawing> </DrawingBrush> <ControlTemplate x:Key="DefaultTimeElapsedControlTemplate" TargetType="{x:Type local:ElapsedTimeControl}"> <Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}"> <Grid Margin="{TemplateBinding Padding}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="10" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <TextBlock Grid.Column="0">Time Elapsed :</TextBlock> <TextBlock Grid.Column="2" Text="{TemplateBinding CurrentTimeString}" /> </Grid> </Border> </ControlTemplate> <GradientStopCollection x:Key="GlassGradientStopCollectionKey"> <GradientStop Offset="0.2" Color="White" /> <GradientStop Offset="0.4" Color="Transparent" /> <GradientStop Offset="0.5" Color="White" /> <GradientStop Offset="0.75" Color="Transparent" /> <GradientStop Offset="0.9" Color="White" /> <GradientStop Offset="1.0" Color="Transparent" /> </GradientStopCollection> <LinearGradientBrush x:Key="GlassLinearGradientBrushKey" StartPoint="0 0" EndPoint="1 1" Opacity="1" GradientStops="{StaticResource GlassGradientStopCollectionKey}" /> <Style TargetType="{x:Type local:ElapsedTimeControl}"> <Setter Property="Template" Value="{StaticResource DefaultTimeElapsedControlTemplate}" /> <Setter Property="BorderThickness" Value="1" /> <Setter Property="BorderBrush"> <Setter.Value> <LinearGradientBrush StartPoint="0.5 0" EndPoint="0.5 1"> <LinearGradientBrush.GradientStops> <GradientStop Offset="0.0" Color="LightBlue" /> <GradientStop Offset="1.0" Color="Gray" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property="Padding" Value="10" /> <Setter Property="Background" Value="{StaticResource GlassLinearGradientBrushKey}" /> </Style> </Window.Resources> <Grid HorizontalAlignment="Center" VerticalAlignment="Center" Width="500"> <Border Background="{StaticResource GridDrawingBrushKey}"> <StackPanel> <local:ElapsedTimeControl x:Name="elapsedTimeControl" Margin="10" Width="300" /> <TextBlock Margin="0 20 0 0">No Acceleration or Deceleration</TextBlock> <Rectangle Name="nonAcceleratedOrDeceleratedRectangle" HorizontalAlignment="Left" Margin="0 10 0 0" Width="10" Height="20" Fill="#aa3333ff" /> <TextBlock Margin="0 20 0 0">AccelerationRatio="0.4"</TextBlock> <Rectangle Name="acceleratedRectangle" HorizontalAlignment="Left" Margin="0 10 0 0" Width="10" Height="20" Fill="#aa3333ff" /> <TextBlock Margin="0 20 0 0">DecelerationRatio="0.6"</TextBlock> <Rectangle Name="deceleratedRectangle" HorizontalAlignment="Left" Margin="0 10 0 0" Width="10" Height="20" Fill="#aa3333ff" /> <TextBlock Margin="0 20 0 0">AccelerationRatio="0.4" DecelerationRatio="0.6"</TextBlock> <Rectangle Name="acceleratedAndDeceleratedRectangle" HorizontalAlignment="Left" Margin="0 10 0 0" Width="10" Height="20" Fill="#aa3333ff" /> <Button HorizontalAlignment="Left" Margin="0 30 0 0" Width="180" Height="30"> Restart Animations <Button.Triggers> <EventTrigger RoutedEvent="Button.Click"> <BeginStoryboard> <Storyboard Name="storyboard"> <DoubleAnimation Storyboard.TargetName="nonAcceleratedOrDeceleratedRectangle" Storyboard.TargetProperty="(Rectangle.Width)" Duration="00:00:10" From="20" To="400" /> <DoubleAnimation Storyboard.TargetName="acceleratedRectangle" Storyboard.TargetProperty="(Rectangle.Width)" Duration="00:00:10" From="20" To="400" AccelerationRatio="0.4" /> <DoubleAnimation Storyboard.TargetName="deceleratedRectangle" Storyboard.TargetProperty="(Rectangle.Width)" Duration="00:00:10" From="20" To="400" DecelerationRatio="0.6" /> <DoubleAnimation Storyboard.TargetName="acceleratedAndDeceleratedRectangle" Storyboard.TargetProperty="(Rectangle.Width)" Duration="00:00:10" From="20" To="400" AccelerationRatio="0.4" DecelerationRatio="0.6" /> </Storyboard> </BeginStoryboard> </EventTrigger> </Button.Triggers> </Button> </StackPanel> </Border> </Grid> </Window> |