示例:WPF应用Behaviors封装的动画加载子项

一、目的:封装一个加载子项动画的行为

二、实现

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

五、下载地址

GitHub下载地址:https://github.com/HeBianGu/WPF-ControlBase.git

发布了76 篇原创文章 · 获赞 33 · 访问量 7万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章