天天看点

第4章 依赖属性(3)——自定义附加属性

一、概述

附加属性也是一种依赖属性,同样由WPF属性系统管理。不同之处在于附加属性被应用到的类并非定义附加属性的那个类。例如,Grid类定义了Row和Column附加属性,这两个属性被用于设置Grid面板包含的元素,以指明这些元素应被放到哪个单元格中。类似地,DockPanel类定义了Dock附加属性,而Canvas类定义了Left、Right、Top和Bottom附加属性。

二、定义和注册附加属性

定义附加属性同定义依赖属性一样,但是注册附加属性需要使用RegisterAttached()方法,而不是使用Register()方法。代码如下:

public static readonly DependencyProperty RowProperty =
    DependencyProperty.RegisterAttached(
        "Row",
		typeof(int),
        typeof(Grid),
        new FrameworkPropertyMetadata(
        0,
        new PropertyChangedCallback(OnCellAttachedPropertyChanged)),
        new ValidateValueCallback(IsIntValueNotNegative));
           

三、封装附加属性

在封装附加属性时不能使用.NET属性封装器,因为附加属性可以被用于任何依赖对象,而不是具体的某个对象。封装附加属性需要调用两个静态方法来设置和获取属性值,这两个方法使用为人熟知的SetValue()和GetValue()方法。这两个静态方法应当命名为SetPropertyName()和Get PropertyName()。代码如下:

public static int GetRow(UIElement element)
{
	if (element == null)
	{
		throw new ArgumentNullException("element");
	}

	return ((int)element.GetValue(RowProperty));
}


public static void SetRow(UIElement element, int value)
{
	if (element == null)
	{
		throw new ArgumentNullException("element");
	}

	element.SetValue(RowProperty, value);
}
           

注意:尽管使用不同的方法注册附加属性和常规的依赖属性,但对于WPF而言它们没有实质性的区别。唯一的区别是XAML解析器是否允许。除非将属性注册为附加属性,否则在标记的其他元素中无法设置。

四、快速创建依赖属性

使用代码片段(code snippet),快捷键为:proppa+两次Tab

继续阅读