附加依賴屬性
什麼時候用
附加屬性是一個依賴屬性,可以應用於任何 DependencyObject
,以增強了解屬性存在的各種控制元件或服務的行為。
附加屬性的一些用例包括:
- 讓父元素迭代其子元素並以某種方式對子元素進行操作。例如,
Grid
控制元件使用Grid.Row
,Grid.Column
,Grid.RowSpan
和Grid.ColumnSpan
附加屬性將元素排列成行和列。 - 使用自定義模板向現有控制元件新增視覺效果,例如在應用範圍內為空文字框新增水印,而無需子類
TextBox
。 - 為部分或全部現有控制元件提供通用服務或功能,例如
ToolTipService
或FocusManager
。這些通常被稱為附加行為。 - 當需要繼承可視樹時,例如類似於
DataContext
的行為。
這進一步說明了 Grid
用例中發生的事情:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Your Name:" />
<TextBox Grid.Column="1" Text="{Binding FirstName}" />
</Grid>
Grid.Column
不是 Label
或 TextBox
上存在的屬性。而是,Grid
控制元件檢視其子元素並根據附加屬性的值排列它們。
如何定義
我們將繼續使用 Grid
作為這個例子。Grid.Column
的定義如下所示,但為了簡潔,排除了 DependencyPropertyChangedEventHandler
。
public static readonly DependencyProperty RowProperty =
DependencyProperty.RegisterAttached("Row", typeof(int), typeof(Grid),
new FrameworkPropertyMetadata(0, ...));
public static void SetRow(UIElement element, int value)
{
if (element == null)
throw new ArgumentNullException("element");
element.SetValue(RowProperty, value);
}
public static int GetRow(UIElement element)
{
if (element == null)
throw new ArgumentNullException("element");
return ((int)element.GetValue(RowProperty));
}
由於附加屬性可以附加到各種各樣的專案,因此它們不能實現為 CLR 屬性。而是引入了一對靜態方法。
因此,與標準依賴項屬性相比,附加屬性也可以在不是從 DependencyObject
派生的類中定義。
適用於常規依賴項屬性的相同命名約定也適用於此:依賴項屬性 RowProperty
具有相應的方法 GetRow
和 SetRow
。
注意事項
如 MSDN 上所述 :
雖然屬性值繼承似乎適用於非附加依賴項屬性,但未定義執行時樹中某些元素邊界的非附加屬性的繼承行為。始終使用 RegisterAttached 來註冊在後設資料中指定 Inherits 的屬性。