當我們建立新的類和成員時,我們花費了大量的時間和精力是它們儘可能的好用,好理解,好發現。通常我們會遵循.Net框架設計指南,尤其是會不斷地研究這個新類與其他類,未來計劃等內容之間的關係。
當命名依賴屬性(DependencyProperty)和依賴物件(DependencyObject)的時候也是遵循這個原則,僅僅討論如何命名,我們就大概花了幾個小時。依賴屬性(DPs)最終歸結為屬性計算和依賴的跟蹤。屬性計算並不是很特別,很多屬性都是這樣的,所以DP的本質特徵就是依賴的跟蹤,因此命名為依賴屬性。
這裡有一個例子,實際上是一段示例程式碼,顯示了幾個依賴跟蹤的例子:
<StackPanel DataContext="Hello, world" TextBlock.FontSize="22">
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontWeight" Value="Bold" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<TextBlock Text="{Binding}" />
</StackPanel>
程式碼示例中TextBlock
的屬性有不少依賴:
TextBlock.Text
依賴於繫結(Binding),而這裡的繫結(Binding)依賴於DataContext
,DataContext
是從父元素StackPanel
繼承下來的,因此,TextBlock.Text
也依賴於樹的形狀;如果TextBlock
從StackPanel
移除,StackPanel
的值也會發生變化。TextBlock.FontSize
也依賴於樹。在這裡,你可以看到它從StackPanel
繼承。- 所有的
TextBlock
屬性都依賴於TextBlock.style
。例如,這裡是TextBlock.FontWeight
來自樣式(Style)。 - 同樣的,
TextBlock.Background
也依賴樣式(Style)。但在這個示例中,它在觸發器(Trigger)中設定。所以TextBlock.Background
在這種情況下也取決於TextBlock.IsMouseOver
。
有時,如果編寫自己的依賴屬性,則需要在跟蹤依賴項上做一些輔助。當需要重新計算屬性時,可以透過呼叫InvalidateProperty
來實現,通常是因為在CoerceValueCallback
中引用了它。
例如,這裡有一個名為Foo
的依賴屬性和一個名為FooPlus1
的只讀依賴屬性。FooPlus1
只是有一個計算“Foo+1”的CoerceValueCallback
。因此,Foo
有一個PropertyChangedCallback
,當Foo
發生變化時,它會使FooPlus1
失效。
public int Foo
{
get { return (int)GetValue(FooProperty); }
set { SetValue(FooProperty, value); }
}
// Using a DependencyProperty as the backing store for Foo. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FooProperty =
DependencyProperty.Register("Foo", typeof(int), typeof(Window1), new PropertyMetadata(FooChangedCallback));
static void FooChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs args)
{
// Whenever Foo changes, we need to invalidate FooPlus1, so that
// the DependencyProperty system knows to update it (call its
// CoerceValueCallback again).
(d as Window1).InvalidateProperty(Window1.FooPlus1Property);
}
public int FooPlus1
{
get { return (int)GetValue(FooPlus1Property); }
}
static readonly DependencyPropertyKey FooPlus1PropertyKey =
DependencyProperty.RegisterReadOnly("FooPlus1", typeof(int), typeof(Window1), new PropertyMetadata(0, null, CoerceFooPlus1Callback));
static readonly DependencyProperty FooPlus1Property = FooPlus1PropertyKey.DependencyProperty;
static object CoerceFooPlus1Callback(DependencyObject d, object baseValue)
{
return (d as Window1).Foo + 1;
}
原文連結:https://learn.microsoft.com/en-us/archive/blogs/mikehillberg/why-is-it-called-a-dependencyproperty