一、目的:封裝一個加載子項動畫的行爲
二、實現
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