WPF中的依赖属性使用

时间:2009-06-26 16:30:13

标签: wpf dependency-properties

我很难找出依赖属性的充分理由。为什么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); }
        }

3 个答案:

答案 0 :(得分:8)

好处主要有两个方面:

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

其次,依赖项属性可以绑定到除为其创建的类型之外的对象。这允许控件可以设置Grid.Column属性的情况,Grid控件可以读取该属性并用于布局。这意味着我们没有数百个装饰器类提供其他控件所需的微小功能。这意味着xmal更直观,更易读。


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

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

简单地说,虽然依赖属性更复杂,以定义普通属性,我仍然会将其用作WPF控件的事实标准,除非有一些很好的理由不这样做。与属性是类的标准的方式大致相同,即使字段更容易实现。

答案 1 :(得分:5)

我要说的主要好处是:

  1. 一流的数据绑定支持。
  2. 清洁附加属性语义
  3. “依赖”的属性值。
  4. 最后一点是

    在依赖关系属性之前,如果值具有本地值,可设置动画的值,可覆盖的值,可设置的值,则可模拟的值将需要声明多个属性/字段/字典条目,以及复杂的状态+优先级管理。

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

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

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

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

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

    Martin还提到了Attached Properties,但是在DependencyProperties出现之前,它们也是可用的(至少在设计师中)。使用DependencyProperties的附加属性实现更加清晰。

答案 2 :(得分:2)

如果要使用绑定来填充属性的值,则需要

依赖项属性。例如,如果它只是普通属性,则无法将Text属性绑定到View Model对象的属性。