【问题标题】:What is the relationship between INotifyPropertyChanged and DependencyProperty?INotifyPropertyChanged 和 DependencyProperty 有什么关系?
【发布时间】:2010-10-27 14:16:51
【问题描述】:

我正在使用 DependencyProperties 构建一个简单的 UserControl 示例,以便可以在 XAML 中更改控件的属性(代码如下)。

当然,在我的应用程序中,我不希望该控件具有紧密耦合的代码隐藏,而是用户控件将是一个名为“DataTypeWholeNumberView”的视图,并且它将拥有自己的名为“DataTypeWholeNumberViewModel”的 ViewModel。

所以我将在 ViewModel 中实现下面的 DependencyProperty 逻辑,但在 ViewModels 中我通常继承 INotifyPropertyChanged,这似乎给了我相同的功能。

那么两者是什么关系:

  1. 将 UserControl XAML 的 DataContext 绑定到其 背后的代码,该代码具有 DependencyProperties
  2. 将 UserControl XAML(视图)的 DataContext 绑定到其 ViewModel(继承自 INotifyPropertyChanged)并具有实现 INotifyPropertyChanged 功能的属性?

XAML:

<UserControl x:Class="TestDependencyProperty827.SmartForm.DataTypeWholeNumber"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel>
        <StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Orientation="Horizontal">
            <TextBlock Text="{Binding Label}"/>
        </StackPanel>
    </StackPanel>
</UserControl>

代码隐藏:

using System.Windows;
using System.Windows.Controls;

namespace TestDependencyProperty827.SmartForm
{
    public partial class DataTypeWholeNumber : UserControl
    {
        public DataTypeWholeNumber()
        {
            InitializeComponent();
            DataContext = this;
        }

        public string Label
        {
            get
            {
                return (string)GetValue(LabelProperty);
            }
            set
            {
                SetValue(LabelProperty, value);
            }
        }

        public static readonly DependencyProperty LabelProperty =
            DependencyProperty.Register("Label", typeof(string), typeof(DataTypeWholeNumber),
            new FrameworkPropertyMetadata());
    }
}

【问题讨论】:

标签: wpf mvvm dependency-properties inotifypropertychanged


【解决方案1】:

使用 WPF,您可以绑定到 DependencyProperties 或实现 INotifyPropertyChanged 的​​属性。这是一个选择问题。

因此,您的问题分为将它们放在代码后面或视图模型中。既然您提到您不希望后面有紧密耦合的代码,那么您最好拥有一个遵循 MVVM 模式的视图模型。

您甚至可以在您的视图模型中使用 DependencyProperties,就像您在后面的代码中所做的那样。

【讨论】:

    【解决方案2】:

    INotifyPropertyChanged 是 .Net 自 2.0 以来存在的接口。它基本上允许对象在属性更改时发出通知。引发此事件时,相关方可以执行某些操作。它的问题是它只发布属性的名称。因此,您最终会使用反射或一些不确定的 if 语句来确定在处理程序中要做什么。

    DependencyProperties 是一种更精细的构造,它支持默认值、以更节省内存和性能的方式更改通知。

    唯一的关系是 WPF 绑定模型支持通过 INotifyPropertyChanged 实现绑定到 DependencyProperties 或标准 Clr 属性。您的 ViewModel 也可以是 DependecyObject,第三个选项是绑定到 ViewModel 的 DependencyProperties!

    Kent Boogaart 写了一个 very interesting article 来说明 ViewModel 是 POCO 还是 DependencyObject。

    【讨论】:

    • 链接好像坏了
    【解决方案3】:

    我真的不认为 DependencyProperties 和 INotifyPropertyChanged 之间存在关系。这里唯一的魔力是 Binding 类/实用程序足够智能,可以识别 DependencyProperty 并直接绑定到它,或者订阅绑定目标的 notify-property-changed 事件并等待触发。

    【讨论】:

    • 您所做的一个障碍是您的模型不是视觉元素。 DependencyProperty 要求你从 FrameworkElement 继承,然后你需要在一些可视化树中,等等等等。如果你看得太近,这有点恶心,而且会变得很毛茸茸。
    • 您的评论并不完全正确。您可以通过从 DependencyObject 基类继承来使用依赖属性。
    • 您确定不在 VisualTree 中的 DependencyObject 与 FrameworkElement 的工作方式相同吗?我过去遇到过这个问题。
    猜你喜欢
    • 1970-01-01
    • 2010-09-22
    • 2011-12-07
    • 2021-06-06
    • 1970-01-01
    • 2016-09-28
    • 2013-07-02
    • 2017-02-06
    相关资源
    最近更新 更多