5

我很难找出依赖属性的充分理由。为什么 System.Controls.TextBox "Text" 属性是依赖属性而不是普通属性?它作为依赖属性有什么好处?

我要完成的一件事是向我的 UserControl 添加一个 ValidationRules 属性,该属性将包含其他验证规则。像这儿:

<customControls:RequiredTextBox.ValidationRules>
                        <validators:NotNullOrEmptyValidationRule ErrorMessage="FirstName cannot be null or empty"/>
                    </customControls:RequiredTextBox.ValidationRules>

问题是我不确定 ValidationRules 属性应该是 DependencyProperty 还是只是一个普通属性。

上面的代码给出了以下错误:

{"Cannot add element to 'ValidationRules'; the property value is null.  Error at object 'LearningWPF.ValidationRules.NotNullOrEmptyValidationRule' in markup file 'LearningWPF;component/addcustomerwindow.xaml' Line 35 Position 66."}

这是 ValidationRules 属性:

 public static readonly DependencyProperty ValidationRulesProperty =
            DependencyProperty.Register("ValidationRules",
                                        typeof (Collection<ValidationRule>), typeof (RequiredTextBox),
                                        new FrameworkPropertyMetadata(null)); 

        public Collection<ValidationRule> ValidationRules
        {
            get { return (Collection<ValidationRule>)GetValue(ValidationRulesProperty); }
            set { SetValue(ValidationRulesProperty, value); }
        }
4

3 回答 3

8

好处主要有两个方面:

首先,依赖属性仅在使用时才创建,这意味着 TextBox 类可以非常高效,内存占用低,因为它占用堆空间的实际属性数量最少。这在 WPF 中尤其重要,因为所有控件都只是越来越多特定类型的集合。如果这些内部类型中的每一个都声明了数十个属性来定义行为和外观,那么像按钮这样的高级控件最终将具有类的大小,其中包含大约一百个属性。

其次,依赖属性可以与创建它们的类型以外的对象相关联。这允许控件可以设置 Grid.Column 属性,Grid 控件可以读取并用于布局的情况。这意味着我们不需要数百个装饰器类来提供其他控件所需的微小功能。这意味着 xmal 更加直观和易读。


编辑以解决您修改后的问题中的示例:

虽然您的验证属性不会从依赖属性中获得太多好处(基本上是到目前为止所有答案中的原因,我只能真正看到我对内存占用的评论正在发挥作用),这当然不是有利的就像文本框的 Text 属性一样,您可能想要绑定它,或者根据其他一些输入来更改它,我仍然会将它实现为依赖属性。我的理由很简单;你没有得到太多,但它也不会花费你任何东西——我从不希望我在自定义控件中使用了基本属性,而当我第一次开始编写它们时,我不断将我的基本属性升级为依赖项,因为我想要一些额外的功能。

简单地说,虽然依赖属性定义一个普通属性更复杂,但我仍然会将它用作 WPF 控件的事实上的标准,除非有很好的理由不这样做。就像属性是类的标准一样,尽管字段更容易实现。

于 2009-06-26T16:34:52.540 回答
5

我要说的主要好处是:

  1. 一流的数据绑定支持。
  2. 清理附加属性语义
  3. “依赖”的属性值。

最后一点是关键

在依赖属性之前,拥有一个值有一个本地值、一个动画值、一个可覆盖值、一个可样式化值、一个可模板化值将需要声明多个属性/字段/字典条目,以及复杂的状态+优先级管理。

依赖属性为您提供了所有这些开箱即用的功能,同时仅声明一个属性。

话虽如此,在您的情况下,如果您不需要利用这些功能,您可能不想将您的 ValidationRules 声明为 DependencyProperty。

如果这样做,您将希望对您的集合(例如非空集合)进行不同的处理。在这个特定示例中,我将使用 Reflector 并查看 .NET TextBox 如何实现其验证集合,并查看您是否可以重用或复制代码。

除非你确定你的轮子会更好,否则重新发明轮子是没有意义的。我个人的经验是,我重新发明的轮子往往会丢失一些东西;)。

正如 Martin Harris 已经指出的那样,DependencyProperties 可以通过将属性值放入字典来限制内存占用,但是这可以(我相信是?)在 DependencyProperties 出现之前由 MSFT 完成。

Martin 还提到了附加属性,但在 DependencyProperties 出现之前,这些属性也可用(至少在设计器中)。使用 DependencyProperties 的附加属性实现更加简洁。

于 2009-06-26T17:30:34.833 回答
2

如果要使用绑定来填充属性的值,则需要依赖属性。例如,如果它只是一个普通属性,您将无法将 Text 属性绑定到 View Model 对象的属性。

于 2009-06-26T16:32:16.160 回答