當我們創建新的類和成員時,我們花費了大量的時間和精力是它們儘可能的好用,好理解,好發現。通常我們會遵循.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