using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace PropertyDemo { /// <summary> /// UserControl1.xaml 的交互逻辑 /// </summary> public partial class UserControl1 : UserControl { public UserControl1() { InitializeComponent(); } /* ************************************************************************** 1:为什么要用到依赖属性 在WPF体系中,只有定义属性为依赖项属性,这个属性才支持样式设置,数据绑定,继承,动画和默认值 2:和普通属性有什么区别 读取和设置是与传统的属性一样,只是使用普通的.net属性过程(property procedure)进行了包装 3: 新建一个依赖属性有哪几步骤 定义、注册和封装 4:注意 只能为依赖对象(DependencyObject的类)添加依赖属性,当然在WPF中基本上都是直接或间接继承DependencyObject 注册依赖属性必须用是静态的,必须用 readonly 关键字 根据约定,定义依赖属性的字段名在普通属性的末尾加上ProPerty 用来区分依赖属性与实际属性的定义 ************************************************************************** */ public static readonly DependencyProperty MyDemoProperty = DependencyProperty.Register ( "MyDemo",//依赖属性名 typeof(Int32),//属性的类型 typeof(UserControl1),//该属性所属的类 new PropertyMetadata ( 1,//默认值 MyDemoChangedCallBack,//属性改变时发生 MyDemoValueCallBack //处理属性的值 ), MyDemoValidateValue//验证属性 ); /* public static readonly DependencyProperty MyDemoProperty = DependencyProperty.Register ( "MyDemo",//依赖属性名 typeof(Int32),//属性的类型 typeof(UserControl1),//该属性所属的类 new FrameworkPropertyMetadata(0, MyDemoChangedCallBack, MyDemoValueCallBack) ); public static readonly DependencyProperty MyDemoProperty = DependencyProperty.Register ( "MyDemo",//依赖属性名 typeof(Int32),//属性的类型 typeof(UserControl1),//该属性所属的类 new UIPropertyMetadata(0, MyDemoChangedCallBack, MyDemoValueCallBack), MyDemoValidateValue ); * ******************************************************************************* * 配置和创建依赖属性的的附加功能时其实有三个不同类来创建PropertyMetadata对象 1、常用的为PropertyMetaData 只支常规的属性元数据 (默认值,propertyChangedCallback和coerceValueCallback) 2、UIPropertyMetadata 和第一点没什么区别 只是在所有的构造中比第一点多了 isAnimationProhibited 参数(用于在属性上禁用动画的布尔值) 3、FrameworkPropertyMetadata 使用提供的默认值和框架元数据选项、指定的回调、可以用来防止属性动画的布尔值及数据绑定更新触发器默认值初始化 以上我个人的理解他们是父子关系 FrameworkPropertyMetadata > UIPropertyMetadata > PropertyMetaData FrameworkPropertyMetadata 无疑的最全的 比如可以是否要求重新绘制元素、是否用于动画、是否支持帮顶表达式,可以从实际情况出发来决定用哪一个 * ******************************************************************************* */ /// <summary> /// 属性改变时发生 /// </summary> /// <param name="obj"></param> /// <param name="e"></param> public static void MyDemoChangedCallBack(DependencyObject obj, DependencyPropertyChangedEventArgs e) { // } /// <summary> /// 当WPF属性系统重新计算依赖项属性值时或者在当前依赖属性所依赖的DependencyObject上显示调用CoerceValue方法时触发 /// 说的通俗一定就是处理属性值 /// </summary> /// <param name="obj"></param> /// <param name="o"></param> /// <returns></returns> public static Object MyDemoValueCallBack(DependencyObject obj, Object o) { if (Convert.ToInt32(o) > 100) { o = 100; } return o; } /// <summary> /// 验证属性 /// </summary> /// <param name="obj"></param> /// <returns></returns> public static Boolean MyDemoValidateValue(Object obj) { if (Convert.ToInt32(obj) <= 0) { return false; } else { return true; } } /// <summary> /// 封装依赖属性 /// </summary> public Int32 MyDemo { get { return (Int32)GetValue(MyDemoProperty); } set { SetValue(MyDemoProperty, value); } } } /* *********************共享依赖属性示例************************************* 一些类会共享同一个依赖属性,尽管这些内有不同的继承层次 ************************************************************************** */ public class MyDemoTwo:DependencyObject { public static readonly DependencyProperty StateProperty = UserControl1.MyDemoProperty.AddOwner(typeof(MyDemoTwo), new PropertyMetadata(1)); public Int32 MyDemo { get { return (Int32)this.GetValue(StateProperty); } set { this.SetValue(StateProperty, value); } } } }