第二章-依赖属性

1、依赖属性

  依赖属性使用效率更高的保存机制,并支持附加功能,如更改通知(change notification)以及属性值继承(在元素树中向下传播默认属性值的能力)。

  依赖项属性也是WPF许多重要功能的基础,包括动画、数据绑定以及样式,在代码中仍可以使用与读取和设置传统的.NET属性相同的方式来读取和设置依赖项属性。

 

2、应用场景

  1、要求属性支持绑定

  2、自定义/拓展控件属性

  3、支持验证/强制回调

  4、属性继承

  5、附加属性

 

3、依赖属性定义

  VS当中使用propdp可创建依赖属性

    public class Dp:DependencyObject
    {
        //定义
        public static readonly DependencyProperty AgeProperty;
        
        //注册
        static Dp()
        {
            //第一个参数为xaml当中应当显示的属性名称
            //第二个参数:该属性的类型
            //第三个参数:该属性所属类型
            //第四个参数:默认值
            AgeProperty = DependencyProperty.Register(
                "Age",
                typeof(int),
                typeof(Dp),
                new PropertyMetadata(0)
                );
        }

        //包装
        public int Age
        {
            get { return (int)GetValue(AgeProperty); }
            set { SetValue(AgeProperty, value); }
        }
    }

 

4、依赖属性值改变回调  

  在PropertyMetadata当中当中传入一个回调函数

  public class Dp:Panel
  {
      //定义
      public static readonly DependencyProperty AgeProperty;
      
      //注册
      static Dp()
      {
          //第一个参数为xaml当中应当显示的属性名称
          //第二个参数:该属性的类型
          //第三个参数:该属性所属类型
          //第四个参数:默认值
          AgeProperty = DependencyProperty.Register(
              "Age",
              typeof(int),
              typeof(Dp),
              new PropertyMetadata(0,OnAgeChange)
              );
      }

      /// <summary>
      /// 改变回调函数
      /// </summary>
      /// <param name="d">发出该改变的依赖对象</param>
      /// <param name="e">发生的事件</param>
      private static void OnAgeChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
          //业务代码
       //e.NewValue
       //e.OldValue

      }

      //包装
      public int Age
      {
          get { return (int)GetValue(AgeProperty); }
          set { SetValue(AgeProperty, value); }
      }
  }

 

5、依赖属性验证回调

  在DependencyProperty.Register注册方法当中传入回调函数

 public class Dp:Panel
 {
     //定义
     public static readonly DependencyProperty AgeProperty;
     
     //注册
     static Dp()
     {
         //第一个参数为xaml当中应当显示的属性名称
         //第二个参数:该属性的类型
         //第三个参数:该属性所属类型
         //第四个参数:默认值
         AgeProperty = DependencyProperty.Register(
             "Age",
             typeof(int),
             typeof(Dp),
             new PropertyMetadata(0,OnAgeChange),
             new ValidateValueCallback(OnAgeChangeValid)
             );
     }

     private static bool OnAgeChangeValid(object value)
     {
         //验证逻辑
         return true;
     }

    

     //包装
     public int Age
     {
         get { return (int)GetValue(AgeProperty); }
         set { SetValue(AgeProperty, value); }
     }
 }

 

6、依赖属性的强制回调

  在PropertyMetadata当中当中传入一个回调函数

  static Dp()
  {
      //第一个参数为xaml当中应当显示的属性名称
      //第二个参数:该属性的类型
      //第三个参数:该属性所属类型
      //第四个参数:默认值
      AgeProperty = DependencyProperty.Register(
          "Age",
          typeof(int),
          typeof(Dp),
          new PropertyMetadata(0,OnAgeChange,ForceCallBack),
          new ValidateValueCallback(OnAgeChangeValid)
          );
  }

 

7、依赖属性继承  

   AgeProperty = DependencyProperty.Register(
       "Age",
       typeof(int),
       typeof(Dp),
       new FrameworkPropertyMetadata(0,FrameworkPropertyMetadataOptions.Inherits),     
       );
    public class Class1:Control
    {


        public int StuAge
        {
            get { return (int)GetValue(StuAgeProperty); }
            set { SetValue(StuAgeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for StuAge.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StuAgeProperty =
            DpTest.AgeProperty.AddOwner( typeof(Class1),
                new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.Inherits));


    }

 

8、附加属性

  使用propa快捷键可快速创建

   public class AttachTest
   {
       //包装
       public static int GetCustPwdProperty(DependencyObject obj)
       {
           return (int)obj.GetValue(CustPwdProperty);
       }

       public static void SetCustPwdProperty(DependencyObject obj, int value)
       {
           obj.SetValue(CustPwdProperty, value);
       }

       // 定义、注册
       public static readonly DependencyProperty CustPwdProperty =
           DependencyProperty.RegisterAttached("CustPwdProperty", typeof(string), typeof(AttachTest), new PropertyMetadata(""));


   }

 

 <PasswordBox local:AttachTest.CustPwdProperty="{Binding Pwd}" Width="60" Height="30"></PasswordBox>

 

将PasswordBox与附加属性之间建立联系:

  

 //附加属性
 public class AttachTest
 {
     //包装
     public static string GetCustPwdProperty(DependencyObject obj)
     {
         return (string)obj.GetValue(CustPwdProperty);
     }

     public static void SetCustPwdProperty(DependencyObject obj, string value)
     {
         obj.SetValue(CustPwdProperty, value);
     }

     // 定义、注册
     public static readonly DependencyProperty CustPwdProperty =
         DependencyProperty.RegisterAttached("CustPwdProperty", typeof(string), typeof(AttachTest), new PropertyMetadata("", OnCustPwdPropertyChanged));

     //当附加属性变化时将PasswordBox的Password修改为附加属性的值
     private static void OnCustPwdPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
     {
         string pwd = (string)e.NewValue;
         PasswordBox passwordBox = d as PasswordBox;//弱转换
         if (passwordBox != null)
         {
             passwordBox.Password = pwd;
         }
     }

     //当PasswordBox的Password变化时将附加属性修改为Password的值

     public static bool GetOrderProperty(DependencyObject obj)
     {
         return (bool)obj.GetValue(OrderProperty);
     }

     public static void SetGetOrderProperty(DependencyObject obj, bool value)
     {
         obj.SetValue(OrderProperty, value);
     }

     // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
     public static readonly DependencyProperty OrderProperty =
         DependencyProperty.RegisterAttached("OrderProperty", typeof(bool), typeof(AttachTest), new PropertyMetadata(true, OnOrderPropertyChanged));

     private static void OnOrderPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
     {
        PasswordBox passwordBox = d as PasswordBox;
         if (passwordBox != null)
         {
             passwordBox.PasswordChanged -= OnPasswordChanged;
             passwordBox.PasswordChanged += OnPasswordChanged;
         }
     }

     private static void OnPasswordChanged(object sender, RoutedEventArgs e)
     {
       PasswordBox dp = sender as PasswordBox;
         SetCustPwdProperty(dp, dp.Password);
     }

 }

 

posted @ 2025-12-13 22:18  nonAny  阅读(4)  评论(0)    收藏  举报