【译】为什么命名“它”为依赖属性(DependencyProperty)

当我们创建新的类和成员时,我们花费了大量的时间和精力是它们尽可能的好用,好理解,好发现。通常我们会遵循.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)依赖于DataContextDataContext是从父元素StackPanel继承下来的,因此,TextBlock.Text也依赖于树的形状;如果TextBlockStackPanel移除,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

相关推荐
笺上知微9 小时前
基于HelixToolkit.SharpDX 渲染3D模型
wpf
晓纪同学2 天前
WPF-03 第一个WPF程序
大数据·hadoop·wpf
光电大美美-见合八方中国芯2 天前
用于无色波分复用光网络的 10.7 Gb/s 反射式电吸收调制器与半导体光放大器单片集成
网络·后端·ai·云计算·wpf·信息与通信·模块测试
晓纪同学2 天前
WPF-02体系结构
wpf
晓纪同学2 天前
WPF-01概述
wpf
海盗12342 天前
OxyPlot 在 WPF 中的使用
.net·wpf
晓纪同学2 天前
WPF-04 XAML概述
wpf
△曉風殘月〆3 天前
如何在WPF中捕获窗口外的事件
wpf
爱吃烤鸡翅的酸菜鱼4 天前
Java 事件发布-订阅机制全解析:从原生实现到主流中间件
java·中间件·wpf·事件·发布订阅
武藤一雄5 天前
WPF中ViewModel之间的5种通讯方式
开发语言·前端·microsoft·c#·wpf