天天看點

第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

繼續閱讀