WPFというかXAMLのアニメーションはその辺柔軟なので、それほど難しくはないです。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<SolidColorBrush x:Key="ProgressBar.Background" Color="#FFE6E6E6"/> | |
<SolidColorBrush x:Key="ProgressBar.Progress" Color="#FF1C61F3"/> | |
<SolidColorBrush x:Key="ProgressBar.Stripe" Color="#33FFFFFF"/> | |
<Style x:Key="StripedProgressBarStyle" TargetType="{x:Type ProgressBar}"> | |
<Setter Property="Background" Value="{StaticResource ProgressBar.Background}"/> | |
<Setter Property="Foreground" Value="{StaticResource ProgressBar.Progress}"/> | |
<Setter Property="Height" Value="20"/> | |
<Setter Property="Template"> | |
<Setter.Value> | |
<ControlTemplate TargetType="{x:Type ProgressBar}"> | |
<Grid x:Name="TemplateRoot"> | |
<VisualStateManager.VisualStateGroups> | |
<VisualStateGroup x:Name="CommonStates"> | |
<VisualState x:Name="Determinate"> | |
<Storyboard RepeatBehavior="Forever"> | |
<RectAnimation Storyboard.TargetName="Stripe" | |
Storyboard.TargetProperty="(Shape.Fill).(TileBrush.Viewport)" | |
Duration="0:0:1" | |
From="0,0,20,20" To="-20,0,20,20"/> | |
</Storyboard> | |
</VisualState> | |
<VisualState x:Name="Indeterminate"/> | |
</VisualStateGroup> | |
</VisualStateManager.VisualStateGroups> | |
<Border Background="{TemplateBinding Background}"/> | |
<Rectangle x:Name="PART_Track"/> | |
<Grid x:Name="PART_Indicator" | |
ClipToBounds="true" | |
HorizontalAlignment="Left"> | |
<Rectangle x:Name="Indicator" Fill="{TemplateBinding Foreground}"/> | |
<Rectangle x:Name="Stripe"> | |
<Rectangle.Fill> | |
<DrawingBrush TileMode="Tile" Stretch="Uniform" | |
Viewport="0,0,20,20" ViewportUnits="Absolute"> | |
<DrawingBrush.Drawing> | |
<GeometryDrawing Brush="{StaticResource ProgressBar.Stripe}"> | |
<GeometryDrawing.Geometry> | |
<PathGeometry> | |
<PathGeometry.Figures> | |
<PathFigureCollection> | |
<PathFigure StartPoint="0,0"> | |
<LineSegment Point="5,0"/> | |
<LineSegment Point="10,5"/> | |
<LineSegment Point="10,10"/> | |
</PathFigure> | |
<PathFigure StartPoint="0,5"> | |
<LineSegment Point="5,10"/> | |
<LineSegment Point="0,10"/> | |
</PathFigure> | |
</PathFigureCollection> | |
</PathGeometry.Figures> | |
</PathGeometry> | |
</GeometryDrawing.Geometry> | |
</GeometryDrawing> | |
</DrawingBrush.Drawing> | |
</DrawingBrush> | |
</Rectangle.Fill> | |
</Rectangle> | |
</Grid> | |
</Grid> | |
<ControlTemplate.Triggers> | |
<Trigger Property="Value" Value="100"> | |
<Setter TargetName="Stripe" Property="Visibility" Value="Collapsed"/> | |
</Trigger> | |
</ControlTemplate.Triggers> | |
</ControlTemplate> | |
</Setter.Value> | |
</Setter> | |
</Style> |
ポイントとしては、連続して描画するタイプの要素をアニメーションさせるときは、その開始位置の値を変えていくようにすれば、比較的簡単にできます。上の例ではDrawingBrushをTileMode="Tile"を指定して敷き詰め、位置をViewportで決めていますが、このXの値を変えてアニメーションさせています。
ここでもう一つポイントとして、アニメーションにはプリミティブな値を変えるDoubleAnimationやColorAnimationをよく使いますが、Viewportの型はRectなので、この中のXはDoubleAnimationでは対象に指定できません。こういう場合は、複合的な値であるRectを変えるRectAnimationが用意されているので、これを使えばいいわけです。
同じようにThickness(Marginの型)を変えるThicknessAnimation、Pointを変えるPointAnimation、Sizeを変えるSizeAnimationもあるので、幾何学的に変化させるアニメーションは大体カバーできます。これら以外にも、AnimationTimelineの派生クラスを見ると、予め用意されているAnimationをチェックできます。