第二章-依赖属性
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); } }
浙公网安备 33010602011771号