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?这不是我的代码。
如果您希望在属性通过代码更改时自动更新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)。正如我对这个问题的回答中所展示的那样,在减少代码膨胀的同时实现自己也是可能的。