一、目的:封装一个加载子项动画的行为
二、实现
1、通过动画依次加载子项显示
2、封装在行为中方便调用
3、设置动画的生成范围、显示时间、显示效果
三、示例
四、实现过程
1、如下定义一个Behavior
/// <summary> 容器内子控件加载时触发喷泉效果</summary>
public class FountainAnimationBehavior : Behavior<FrameworkElement>
{
protected override void OnAttached()
{
AssociatedObject.Loaded += AssociatedObject_Loaded;
}
private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
{
if (IsUseAll)
{
var items = AssociatedObject.GetChildren<UIElement>().Where(l=>l.RenderTransform is TransformGroup);
items = items.Where(l => (l.RenderTransform as TransformGroup).Children.Count == 4);
StoryBoardService.FountainAnimation(items, PointLeft, PointTop, Mul, MiddleValue, EndValue, Split);
}
else
{
if(AssociatedObject is Panel panel)
{
var items = panel.Children?.Cast<UIElement>()?.Where(l => l.RenderTransform is TransformGroup);
items = items.Where(l => (l.RenderTransform as TransformGroup).Children.Count == 4);
StoryBoardService.FountainAnimation(items, PointLeft, PointTop, Mul, MiddleValue, EndValue, Split);
}
}
}
protected override void OnDetaching()
{
AssociatedObject.Loaded -= AssociatedObject_Loaded;
}
public bool IsUseAll
{
get { return (bool)GetValue(IsUseAllProperty); }
set { SetValue(IsUseAllProperty, value); }
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsUseAllProperty =
DependencyProperty.Register("IsUseAll", typeof(bool), typeof(FountainAnimationBehavior), new PropertyMetadata(false, (d, e) =>
{
FountainAnimationBehavior control = d as FountainAnimationBehavior;
if (control == null) return;
}));
/// <summary> 左右范围 </summary>
public int PointLeft
{
get { return (int)GetValue(PointLeftProperty); }
set { SetValue(PointLeftProperty, value); }
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PointLeftProperty =
DependencyProperty.Register("PointLeft", typeof(int), typeof(FountainAnimationBehavior), new PropertyMetadata(-500, (d, e) =>
{
FountainAnimationBehavior control = d as FountainAnimationBehavior;
if (control == null) return;
}));
/// <summary> 上下范围 </summary>
public int PointTop
{
get { return (int)GetValue(PointTopProperty); }
set { SetValue(PointTopProperty, value); }
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PointTopProperty =
DependencyProperty.Register("PointTop", typeof(int), typeof(FountainAnimationBehavior), new PropertyMetadata(500, (d, e) =>
{
FountainAnimationBehavior control = d as FountainAnimationBehavior;
if (control == null) return;
}));
/// <summary> 放大倍数 </summary>
public double Mul
{
get { return (double)GetValue(MulProperty); }
set { SetValue(MulProperty, value); }
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MulProperty =
DependencyProperty.Register("Mul", typeof(double), typeof(FountainAnimationBehavior), new PropertyMetadata(10.0, (d, e) =>
{
FountainAnimationBehavior control = d as FountainAnimationBehavior;
if (control == null) return;
}));
/// <summary> 放大时间点 </summary>
public double MiddleValue
{
get { return (double)GetValue(MiddleValueProperty); }
set { SetValue(MiddleValueProperty, value); }
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MiddleValueProperty =
DependencyProperty.Register("MiddleValue", typeof(double), typeof(FountainAnimationBehavior), new PropertyMetadata(0.1, (d, e) =>
{
FountainAnimationBehavior control = d as FountainAnimationBehavior;
if (control == null) return;
}));
/// <summary> 还原时间点 </summary>
public double EndValue
{
get { return (double)GetValue(EndValueProperty); }
set { SetValue(EndValueProperty, value); }
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty EndValueProperty =
DependencyProperty.Register("EndValue", typeof(double), typeof(FountainAnimationBehavior), new PropertyMetadata(1.0, (d, e) =>
{
FountainAnimationBehavior control = d as FountainAnimationBehavior;
if (control == null) return;
}));
public double Split
{
get { return (double)GetValue(SplitProperty); }
set { SetValue(SplitProperty, value); }
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SplitProperty =
DependencyProperty.Register("Split", typeof(double), typeof(FountainAnimationBehavior), new PropertyMetadata(0.05, (d, e) =>
{
FountainAnimationBehavior control = d as FountainAnimationBehavior;
if (control == null) return;
}));
}
2、在Xaml中设置行为
<Grid>
<h:Interaction.Behaviors>
<h:FountainAnimationBehavior IsUseAll="True" PointLeft="-2000" PointTop="2000" Split="0.2"/>
</h:Interaction.Behaviors>
3、在Grd子项中设置 RenderTransform="{StaticResource S.TransformGroup.Default}"
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" RenderTransform="{StaticResource S.TransformGroup.Default}">
<TextBlock VerticalAlignment="Center">
<Run Text="总帧数"/>
<Run Text=":" />
</TextBlock>
<TextBlock VerticalAlignment="Center">
<Run Text="{Binding StoryBoardPlayerViewModel.Value}"/>
<Run Text="/" />
<Run Text="{Binding StoryBoardPlayerViewModel.MaxValue}"/>
</TextBlock>
</StackPanel>
其中,S.TransformGroup.Default资源如下
<TransformGroup x:Key="S.TransformGroup.Default">
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
设置如上几个过程就会在Grid Loaded时显示上图示例效果,其中可以设置Behavior的其他参数改变加载效果如动画范围,动画时间,应用范围等等
(部分代码源于开源项目特此说明)
https://www.cnblogs.com/ZXdeveloper/p/7837682.html