• Fasetto.Word P12---Attached Property and Animations


    1,附加的依赖性属性的建立和使用.

    • 附加依赖性属性的建立
     public static readonly DependencyProperty Value = DependencyProperty.RegisterAttached("Value",
                                                            typeof(Property),
                                                            typeof(BaseAttachedProperty<Parent, Property>),
                                                            new UIPropertyMetadata(default(Property), new PropertyChangedCallback(OnValuePropertyChanged),
                                                                new CoerceValueCallback(OnValuePropertyUpdated)
                                                                )
                );
    1. UIPropertyMetadata,的几个参数:
      public UIPropertyMetadata(object defaultValue, PropertyChangedCallback propertyChangedCallback, CoerceValueCallback coerceValueCallback);
          进行附加依赖项属性设置时,有三个步骤:
         image

    2,创建 AnimateBaseProperty
     public class BaseAnimateAttachedProperty<Parent> : BaseAttachedProperty<Parent, bool>
            where Parent : new()
        {
            public bool FirstLoad { get; private set; } = true;
    
            /// <summary>
            /// when value first loaded or changed then animiate
            /// </summary>
            /// <param name="d"></param>
            /// <param name="value"></param>
            public override void OnValueUpdated(DependencyObject d, object value)
            {
                // check if it's a framework element 
                if (!(d is FrameworkElement element)) return;
    
    
                // if value is same and not first load then return
                if (element.GetValue(ValueProperty) == value && !FirstLoad) return;
    
                if (FirstLoad)
                {
                    //  only load once track to delay do animation until the element loaded
                    //because the Attached element is 
                    RoutedEventHandler load = null;
    
                    load = (ss, ee) =>
                      {
                          element.Loaded -= load;
                          FirstLoad = false;
                          DoAnimation(element, (bool)value);
                      };
                    element.Loaded += load;
                }
                else
                    DoAnimation(element, (bool)value);
            }
    
            public virtual void DoAnimation(FrameworkElement element, bool value)
            {
    
            }
        }
        #endregion
    • 当附加依赖项的值改变时,触发OnValueChangedUpdate,然后再触发DoAnimation
    • 当FirstLoad时,进行一个自解绑的事件绑定.

    3,建立SlideInAndOutFromLeftProperty

     public class SlideInAndOutFromLeftProperty:BaseAnimateAttachedProperty<SlideInAndOutFromLeftProperty>
        {
            public override async void DoAnimation(FrameworkElement element, bool value)
            {
                if (value)
                {
                    await element.SlideAndFadeInFromLeftAsync(FirstLoad?0:0.3f, false);
                }
                else
                    await element.SlideAndFadeOutToLeftAsync(FirstLoad ? 0 :0.3f, false);
            }
    
        }
    • FirstLoad的作用是,当第一次进行动画时,一步到位.设定动画的Duration=0;

    4,更新StoryHelper和Animations里面的类.

    public static void AddSlideToRight(this Storyboard storyboard, float seconds, double offset, float accelerationRatio = 0.1f, bool keepMargin = true)
            {
                //Create a ThicknessAnimation
                var slideAnimation = new ThicknessAnimation
                {
                    Duration = new Duration(TimeSpan.FromSeconds(seconds)),
                    From = new Thickness(0),
                    To = new Thickness(keepMargin ? offset : 0, 0, -offset , 0),
                    AccelerationRatio = accelerationRatio,
                };
    
                //Bind the Ainimation and the PropertyPath"Margin"
                Storyboard.SetTargetProperty(slideAnimation, new PropertyPath("Margin"));
    
                //Add it to the StoryBoard
                storyboard.Children.Add(slideAnimation);
            }
    • keepMargin的作用是,当动画结束时候是否保持源控件在布局中的Margin.

    5,在ApplicationViewModel中添加SlideMenuVisible.

    public bool SlideMenuVisible { get; set; } = false;

    6,在MainWindow.xaml中添加代码
     <!--SideMenuControl-->
                <local:SidemenuControl
                    d:DataContext="{x:Null}"
                    DataContext="{x:Null}"
                    Width="300"
                    local:SlideInAndOutFromLeftProperty.Value="{Binding ApplicationViewModel.SlideMenuVisible,Source={x:Static local:ApplicationLocator.Instance}}"
                    Visibility="{Binding ApplicationViewModel.SlideMenuVisible,Source={x:Static local:ApplicationLocator.Instance},
                      Converter={local:BooleanToVisibilityConverter},ConverterParameter=True }">
                    <local:ChatListControl/>
                </local:SidemenuControl>
    • 将SlideInAndOutFromLeftProperty附加属性绑定到SlideMenuVisible上,那么,当其为false,或者true的时候,调用OnvalueUpdate,就会触发相应的动画.
    • Visiblity绑定到SlideMenuVisible上面,当其为false时,不显示画面.

    7,在LoginViewModel中测试代码

    public async Task LoginAsycn(object parameter)
            {
                IoC.Get<ApplicationViewModel>().SlideMenuVisible ^= true;
                return;
                await RunCommand(() => LoginIsRunning, async () =>
                 {
                     //body of a async work!
                     await Task.Delay(1000);
                     var email = Email;
                     SecurePassword = ((IHavePassword)parameter).SecurePassword;
                     var password = SecurePassword.Unsecure();
                 });
    
            }

    8,结果展示

    imageimage

  • 相关阅读:
    利用 localStorage 储存css js
    实现图片延迟加载的一些 库
    less 应用
    vue 问题集合||
    一个简易的登录框
    python_协程方式操作数据库
    爬取知名社区技术文章_分析_1
    python_爬百度百科词条
    python_爬校花图片
    python_猜年龄
  • 原文地址:https://www.cnblogs.com/frogkiller/p/14505342.html
Copyright © 2020-2023  润新知