■ ContentControl 클래스를 사용해 원형 파급 효과 애니메이션 컨트롤을 만드는 방법을 보여준다.
▶ RippleEffectDecorator.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 |
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace TestProject { /// <summary> /// 파급 효과 장식자 /// </summary> public class RippleEffectDecorator : ContentControl { //////////////////////////////////////////////////////////////////////////////////////////////////// Dependency Property ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 하이라이트 배경 속성 - HighlightBackgroundProperty /// <summary> /// 하이라이트 배경 속성 /// </summary> public static readonly DependencyProperty HighlightBackgroundProperty = DependencyProperty.Register ( "HighlightBackground", typeof(Brush), typeof(RippleEffectDecorator), new PropertyMetadata(Brushes.White) ); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 그리드 /// </summary> private Grid grid; /// <summary> /// 타원 /// </summary> private Ellipse ellipse; /// <summary> /// 스토리보드 /// </summary> private Storyboard storyboard; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 하이라이트 배경 - HighlightBackground /// <summary> /// 하이라이트 배경 /// </summary> public Brush HighlightBackground { get { return (Brush)GetValue(HighlightBackgroundProperty); } set { SetValue(HighlightBackgroundProperty, value); } } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Static #region 생성자 - RippleEffectDecorator() /// <summary> /// 생성자 /// </summary> static RippleEffectDecorator() { DefaultStyleKeyProperty.OverrideMetadata ( typeof(RippleEffectDecorator), new FrameworkPropertyMetadata(typeof(RippleEffectDecorator)) ); } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 템플리트 적용시 처리하기 - OnApplyTemplate() /// <summary> /// 템플리트 적용시 처리하기 /// </summary> public override void OnApplyTemplate() { base.OnApplyTemplate(); this.grid = GetTemplateChild("PART_GRID") as Grid; this.ellipse = GetTemplateChild("PART_ELLIPSE") as Ellipse; this.storyboard = grid.FindResource("PART_STORYBOARD") as Storyboard; AddHandler ( MouseDownEvent, new RoutedEventHandler ( (sender, e) => { double targetWidth = Math.Max(ActualWidth, ActualHeight) * 2; Point mousePoint = (e as MouseButtonEventArgs).GetPosition(this); Thickness startMargin = new Thickness(mousePoint.X, mousePoint.Y, 0, 0); this.ellipse.Margin = startMargin; (this.storyboard.Children[0] as DoubleAnimation ).To = targetWidth; (this.storyboard.Children[1] as ThicknessAnimation).From = startMargin; (this.storyboard.Children[1] as ThicknessAnimation).To = new Thickness(mousePoint.X - targetWidth / 2, mousePoint.Y - targetWidth / 2, 0, 0); this.ellipse.BeginStoryboard(this.storyboard); } ), true ); } #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 |
<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="MainWindow" FontFamily="나눔고딕코딩" FontSize="16"> <Window.Resources> <Style TargetType="{x:Type local:RippleEffectDecorator}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:RippleEffectDecorator}"> <Grid Name="PART_GRID" Width="{Binding ElementName=PART_CONTENTPRESENTER, Path=ActualWidth}" Height="{Binding ElementName=PART_CONTENTPRESENTER, Path=ActualHeight}" Background="{TemplateBinding Background}" ClipToBounds="True"> <Grid.Resources> <Storyboard x:Key="PART_STORYBOARD" Storyboard.TargetName="PART_ELLIPSE"> <DoubleAnimation Storyboard.TargetProperty="Width" From="0" /> <ThicknessAnimation Storyboard.TargetProperty="Margin" /> <DoubleAnimation Storyboard.TargetProperty="Opacity" BeginTime="00:00:01" Duration="00:00:00.25" From="1" To="0" /> <DoubleAnimation Storyboard.TargetProperty="Width" BeginTime="00:00:01.25" Duration="00:00:00" To="0" /> <DoubleAnimation Storyboard.TargetProperty="Opacity" BeginTime="0:0:1.25" Duration="0:0:0" To="1" /> </Storyboard> </Grid.Resources> <Ellipse Name="PART_ELLIPSE" HorizontalAlignment="Left" VerticalAlignment="Top" Width="0" Height="{Binding Path=Width, RelativeSource={RelativeSource Self}}" Fill="{Binding Path=HighlightBackground, RelativeSource={RelativeSource TemplatedParent}}" /> <ContentPresenter Name="PART_CONTENTPRESENTER" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> <Grid> <local:RippleEffectDecorator HorizontalAlignment="Center" VerticalAlignment="Center" Width="500" Height="300" Background="Orange" HighlightBackground="Yellow"> <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="72" FontWeight="Bold" Text="Click mouse!" /> </local:RippleEffectDecorator> </Grid> </Window> |