using of INotifyPropertyChanged

本文关键字:INotifyPropertyChanged of using | 更新日期: 2023-09-27 18:21:21

有人能解释一下在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?这不是我的代码。

using of INotifyPropertyChanged

如果您希望在属性通过代码更改时自动更新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));
}

当您绑定到StudentData的属性(如StudentFirstName)时,绑定类将测试StudentDataNotifyPropertyChanged接口。如果是,则它将挂接到PropertyChanged事件中。当事件触发并且由于StudentFirstName属性而触发时,它知道需要再次恢复源值,因为它已经更改。这就是绑定能够监视源中的更改并将其反映在用户界面中的方式。

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

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