附加属性的使用
附加属性
一、为什么需要定义附加属性:
- WPF中,附加属性经常用于控件属性。
- 附加属性是一种依赖属性,与依赖属性不同的是,附加属性被应用的类不是定义附加属性的类。即给任何需要的控件(类)提供该属性的使用入口。
- 某个依赖属性本来不属于某个对象,但由于某种需求,该对象需要这个依赖属性,这时就需要将该依赖属性定义为附加属性。
二、创建附加属性的快捷方式:输入propa,再敲两次Tab键
三、不使用属性封装器:因为附加属性是可以被用于任何对象。
- 通过调用两个静态方法分别包装SetValue()和GetValue(),这两个方法应当命名为SetPropertyName()和GetPropertyName()。
1 public static bool GetIsRotate(DependencyObject obj) 2 { 3 return (bool)obj.GetValue(IsRotateProperty); 4 } 5 6 public static void SetIsRotate(DependencyObject obj, bool value) 7 { 8 obj.SetValue(IsRotateProperty, value); 9 }
四、附加属性的定义:
(1)利用快捷键生成的附加属性模板如下:需要使用RigisterAttached方法。
1 public static readonly DependencyProperty MyPropertyProperty = 2 DependencyProperty.RegisterAttached("MyProperty", typeof(int), typeof(ownerclass), new PropertyMetadata(0));
(2)注册附加属性的方式有多种,上述是最常用的一种。注册参数最多有五个:
1 public static DependencyProperty RegisterAttached(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata, ValidateValueCallback validateValueCallback);
(3)在模板基础上编辑自己的附加属性IsRotate:
1 public static readonly DependencyProperty IsRotateProperty = 2 DependencyProperty.RegisterAttached("IsRotate", typeof(bool), typeof(YMDemo), new PropertyMetadata(false));
-
参数一(IsRotate):要注册的附加属性的名称。
-
参数二(typeof(bool)):声明属性IsRotate的类型是bool。
-
参数三(typeof(YMDemo)):依赖属性IsRotate的所有者类型,即定义该附加属性的类是YMDemo。
-
参数四的类型是PropertyMetadata类:该类有5个重载的构造函数,参数最多是三个,示例中使用的是传参为DefaultValue的构造函数。
1 public PropertyMetadata(object defaultValue); 2 3 public PropertyMetadata(object defaultValue, PropertyChangedCallback propertyChangedCallback, CoerceValueCallback coerceValueCallback);
-
DefaultValue:附加属性未被显式赋值时,使用该默认值。
-
PropertyChangedCallback:附加属性的值被改变之后,此委托会被调用,此委托可关联一个影响函数。
-
CoerceValueCallback:附加属性值被强制改变时此委托会被调用,对赋值进行检查,强制对值进行赋值,返回值为Object类型,这个才是要赋给属性的值,此委托可关联一个影响函数。
五、属性value更改后,发生校正的流程:
六、依赖属性的使用
(1)在YMDemo.xaml.cs中定义附加属性IsRotate,附加属性总是使用包含两个部分的命名形式:定义类型.属性名;
(2)在MainWindow.xaml中如果想要Grid控件使用IsRotate属性:
<Window x:Class="DependencyPropertyDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:DependencyPropertyDemo" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800">
<Grid x:Name ="grdRotate" local:YMDemo.IsRotate="True"/> </Window>
附加属性不是真正的属性,它们实际上被转换为方法调用。XAML解析器以这种形式调用静态方法:DefiningType.SetPropertyName().例如, 定义类型是YMDemo类,并且属性是IsRotate,所以解析器调用YMDemo.SetIsRotate方法。当调用SetPropertyName()方法时,解析器传递两个参数,被修改的对象和指定的属性值,即YMDemo.SetIsRotate(grdRotate,True).