目次
- WPFのCustomControlでアニメーション-概要
- LineにLinearGradientBrushを適用したものをCustomControlとして作る
- Storyboardを作成する(XAML)
- Storyboardを切り替える(XAML)←ここ
- Storyboardを切り替える(Code Behind)
- Storyboardを作成する(Code Behind)
目的
プロパティによって動作するStoryboardを切り替える
作成
.cs
- 切り替えに必要な依存関係プロパティ(
AnimationType
、面倒なのでbool)を作成する
Generic.xaml側
- 必要なだけStoryboardを作成する(true時(gradientAnimationTrue),false時(gradientAnimationFalse)の二種類)
ControlTemplate.Trigger
でプロパティと対応するStoryboardを設定する
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:GradientLineTest.Controls" > <Style TargetType="{x:Type local:GradientLineControl}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:GradientLineControl}"> <ControlTemplate.Resources> <Storyboard x:Key="gradientAnimationTrue" RepeatBehavior="Forever" AutoReverse="True"> <DoubleAnimation Storyboard.TargetName="gradientLine" Storyboard.TargetProperty="(Line.Stroke).(LinearGradientBrush.GradientStops)[1].(GradientStop.Offset)" From="0" To="1"/> </Storyboard> <Storyboard x:Key="gradientAnimationFalse" RepeatBehavior="Forever" AutoReverse="True"> <DoubleAnimation Storyboard.TargetName="gradientLine" Storyboard.TargetProperty="(Line.Stroke).(LinearGradientBrush.GradientStops)[0].(GradientStop.Offset)" From="0" To="1"/> <DoubleAnimation Storyboard.TargetName="gradientLine" Storyboard.TargetProperty="(Line.Stroke).(LinearGradientBrush.GradientStops)[1].(GradientStop.Offset)" From="0" To="1"/> </Storyboard> </ControlTemplate.Resources> <ControlTemplate.Triggers> <Trigger Property="AnimationType" Value="True"> <Trigger.EnterActions> <BeginStoryboard x:Name="typeTrueAnimation" Storyboard="{StaticResource gradientAnimationTrue}"/> </Trigger.EnterActions> <Trigger.ExitActions> <RemoveStoryboard BeginStoryboardName="typeTrueAnimation"/> </Trigger.ExitActions> </Trigger> <Trigger Property="AnimationType" Value="False"> <Trigger.EnterActions> <BeginStoryboard x:Name="typeFalseAnimation" Storyboard="{StaticResource gradientAnimationFalse}"/> </Trigger.EnterActions> <Trigger.ExitActions> <RemoveStoryboard BeginStoryboardName="typeFalseAnimation"/> </Trigger.ExitActions> </Trigger> </ControlTemplate.Triggers> <Line x:Name="gradientLine" X1="{TemplateBinding X1}" Y1="{TemplateBinding Y1}" X2="{TemplateBinding X2}" Y2="{TemplateBinding Y2}" StrokeThickness="10" > <Line.Stroke> <LinearGradientBrush StartPoint="0.0,0.5" EndPoint="1.0,0.5"> <GradientStop Color="{Binding LeftColor,RelativeSource={RelativeSource TemplatedParent}}" Offset="0.0"/> <GradientStop Color="{Binding RightColor,RelativeSource={RelativeSource TemplatedParent}}" Offset="1"/> </LinearGradientBrush> </Line.Stroke> </Line> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
注意点
Storyboardを書く場所について
Storyboardは<ControlTemplate.Triggers>
から見える場所(<ControlTemplate.Resources>
か<Style.Resources>
)に書く。
<Line.Resources>
に書くと<ControleTemplate.Triggers>
から見えない(方法はあるのかもしれないけど知らない)。
Storyboard切り替え時の処理について
別のStoryboardを動かすなら元のStoryboardは止めないと混ざって期待通りの動作にならない。
(<Trigger.ExitActions>
のとこに<RemoveStoryboard>
を書いてプロパティが変わったら削除するようにしてる。止める場合は<StopStoryboard>
だけどいろいろめんどそうだったので削除を使ってる)