WPF 中的依赖属性使用

发布于 2024-07-25 03:07:44 字数 1419 浏览 4 评论 0原文

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

我想要完成的事情之一是将 ValidationRules 属性添加到我的 UserControl 中,该属性将包含其他验证规则。 像这里一样:

<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); }
        }

I am having a hard time figuring out good reasons for the dependency property. Why the System.Controls.TextBox "Text" property a dependency property and not a normal property? What benefits does it serve being a dependency property?

One of the things I am trying to accomplish is to add a ValidationRules property to my UserControl which will contain other validation rules. Like here:

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

The problem is that I am not sure if ValidationRules property should be DependencyProperty or just a normal property.

The above code gives the following error:

{"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."}

Here is the ValidationRules property:

 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); }
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

深爱不及久伴 2024-08-01 03:07:44

好处主要有两个:

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

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


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

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

简而言之,虽然依赖属性的定义比普通属性更复杂,但我仍然会使用它作为 WPF 控件的事实上的标准,除非有充分的理由不这样做。 就像属性是类的标准一样,尽管字段更容易实现。

The benefits are primarily two fold:

Firstly a dependency property is only created when it is used, this means the TextBox class can be very efficient, with a low memory footprint since it has a minimal number of real properties taking up space on the heap. This is especially important in WPF where all controls are just collections of more and more specific types. If each of those inner types declared tens of properties to define behaviour and look then a high level control like a button would end up having the size of a class with something in the ballpark of a hundred properties.

Secondly dependency properties can be tied to an object other than the type that they are created for. This allows the case where a control can set a Grid.Column property, which the Grid control can read and use for layout. This means that we don't hundreds of decorator classes supplying tiny pieces of functionality required by other controls. This means that xmal is far more intuitive and readable.


Edited to address the example in your revised question:

While your validation property won't gain much benefit from being a dependency property (basically out of the reasons in all the answers so far I can only really see my comment of memory footprint coming in to play), and it certainly isn't advantageous as it is in the case of the Text property of a text box where you may want to bind it, or change it based on some other input, I would still implement it as a dependency property. My reasoning for this is simple; you don't gain much, but it also doesn't cost you anything - I have never wished I had used a basic property in a custom control whereas when I first started writing them I was constantly upgrading my basic properties to dependencies because I wanted some extra functionality.

Simply put, while the dependency property is more complex to define that a normal property I would still use it as the de facto standard for WPF controls unless there was some good reason to do otherwise. In much the same way as a property is the standard for classes, even though a field is easier to implement.

泅渡 2024-08-01 03:07:44

我想说的主要好处是:

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

最后一点是key

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

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

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

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

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

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

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

The primary benefits I would say are:

  1. First-class data binding support.
  2. Clean Attached Property semantics
  3. Property values which "depend".

That last point is key

Before Dependency Properties, having a value have a local value, an animatable value, an overridable value, a styleable value, a templatable value would require the declaration of multiple Properties/Fields/Dictionary entries, as well as complex state+precedence management.

Dependency Properties give you all these features out of the box, while declaring just ONE property.

That being said, in your case, you may not want to declare your ValidationRules as a DependencyProperty if you won't need to take advantage of these features.

If you do, you'll want to have different handling for your collections (non-empty collections for example). In this particular example, I would use Reflector and see how the .NET TextBox implements their validation collections, and see if you can reuse or copy the code.

There's no point re-inventing the wheel unless you're certain your wheel will be better. My personal experience is that my reinvented wheels tend to be missing things ;).

As Martin Harris already pointed out, DependencyProperties can limit the memory footprint by throwing the property values into a dictionary, however this can (and I believe was?) done by MSFT before the advent of DependencyProperties.

Martin also mentions Attached Properties, but those were also available (at least in designer) before the advent of DependencyProperties. The Attached Property implementation using DependencyProperties is much cleaner.

哆啦不做梦 2024-08-01 03:07:44

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

Dependency Properties are required if you want to use binding to populate the value of a property. If it was just a normal property, you wouldn't be able to bind the Text property to a property of your View Model object, for example.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文