첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
0.01MB

▶ RippleEffectDecorator.cs

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
    }
}

 

728x90

 

▶ MainWindow.xaml

<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>
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요