使用INotifyPropertyChanged

3
有人能够解释一下在WPF中使用绑定时为什么需要实现INotifyPropertyChanged接口吗?我不实现这个接口也可以绑定属性吗?例如,我有下面这段代码:
public class StudentData : INotifyPropertyChanged
{
    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;
    #endregion

    void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    string _firstName = null;
    public string StudentFirstName
    {
        get
        {
            return _firstName;
        }
        set
        {
            _firstName = value;

            OnPropertyChanged("StudentFirstName");
        }
    }
}

在 XAML 中进行绑定
<TextBox Text="{Binding Path=StudentFirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
   Grid.Row="1"
   Grid.Column="2"
   VerticalAlignment="Center" />

这段代码来自.xaml.cs文件

StudentData _studentData = new StudentData { StudentFirstName = "John", StudentGradePointAverage = 3.5};

public MainWindow()
{
    InitializeComponent();

    this.DataContext = _studentData;
}

为什么在这种情况下需要使用INotifyPropertyChanged? 这不是我的代码。

我建议你看一些关于Fody和MVVMLight与WPF的例子,也许对你会非常有帮助XD。 - Joel R Michaliszen
移除 INotifyPropertyChanged 并尝试在按钮点击时更改学生的名称。 - D J
@dj 它正在改变中... - user4568872
3个回答

1
如果您想让 WPF 表单在属性通过代码更改时自动更新,那么您需要使用 INotifyPropertyChanged。此外,一些控制器可能希望知道是否进行了编辑以启用/禁用保存按钮等。您还可能在不同视图上显示相同的属性;在这种情况下,INotifyPropertyChanged 有助于在编辑属性时立即更新其他视图。
如果您认为您的表单在没有 INotifyPropertyChanged 的情况下表现良好,则可以放弃它。
请注意,即使没有 INotifyPropertyChanged,绑定也可以工作。参见:为什么实现 INotifyPropertyChanged 后数据绑定能够正常工作?
我会这样实现属性。在一些罕见的情况下,它可以帮助避免无限循环更新。顺便说一下,这样更有效率。
 private string _firstName;
 public string StudentFirstName
 {
     get { return _firstName; }
     set
     {
         if (value != _firstName) {
             _firstName = value;
             OnPropertyChanged("StudentFirstName");
         }
     }
 }

从C#6.0(VS 2015)开始,您可以像这样实现OnPropertyChanged

private void OnPropertyChanged(string propertyName)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

OnPropertyChanged(...)会引发事件,表示我的属性已经被更改了,对吗? - user4568872

1

当您绑定到 StudentData 的属性,例如 StudentFirstName 时,绑定类会测试该实例是否提供 INotifyPropertyChanged 接口。如果是,则它将钩入 PropertyChanged 事件。当事件触发并且因为 StudentFirstName 属性而触发时,它知道需要再次恢复源值,因为它已经改变了。这就是绑定如何能够监视源中的更改并在用户界面中反映它们的方式。

如果您不提供 INotifyPropertyChanged 接口,则绑定不知道源值何时更改。在这种情况下,当属性更改时,用户界面不会更新。您只会看到在首次使用绑定时定义的初始值。


0

它确实需要被实现以使绑定工作,但这并不意味着你总是必须自己去做。还有其他选择,比如Castle Dynamic Proxy(将你的类包装在代理中,并向所有虚拟属性注入INPC)和Fody(在后处理步骤中将其添加到IL中)。同时,你也可以自己实现,同时减少代码膨胀,就像我在对这个问题的回答中所演示的那样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接