728x90
반응형
728x170
▶ 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
반응형
그리드형(광고전용)
'C# > WPF' 카테고리의 다른 글
[C#/WPF] ControlTemplate 엘리먼트 : ToggleButton 엘리먼트를 정의해 재생 버튼 만들기 (0) | 2022.07.23 |
---|---|
[C#/WPF] ListBox 엘리먼트 : IsSynchronizedWithCurrentItem 속성을 사용해 현재 항목 동기화 설정하기 (0) | 2022.05.28 |
[C#/WPF] DateTemplate 클래스 : FindName 메소드를 사용해 자식 객체 구하기 (0) | 2022.05.28 |
[C#/WPF] ControlTemplate 엘리먼트 : Button 엘리먼트 정의하기 (0) | 2022.05.25 |
[C#/WPF] ContentPresenter 엘리먼트 : RecognizesAccessKey 속성을 사용해 액세스 키 사용 여부 설정하기 (0) | 2022.05.25 |
[C#/WPF] WebBrowser 엘리먼트 : 스크립트 오류 억제하기 (0) | 2022.05.24 |
[C#/WPF] InputMethod 엘리먼트 : PreferredImeState/PreferredImeConversionMode 첨부 속성을 사용해 한글 모드에서 입력 시작하기 (0) | 2022.05.24 |
[C#/WPF] MessageBox 클래스 : Show 정적 메소드를 사용해 최상위 메시지 박스 표시하기 (0) | 2022.05.14 |
[C#/WPF] 환형 진행바 애니메이션 만들기 (0) | 2022.05.07 |
[C#/WPF] Storyboard 엘리먼트 : 슬라이딩 패널 만들기 (0) | 2022.02.04 |
댓글을 달아 주세요