INotifyPropertyChanged-更改PropertyName不会产生任何效果
本文关键字:任何效 更改 PropertyName INotifyPropertyChanged- | 更新日期: 2023-09-27 18:26:46
我正在尝试将Winforms UI绑定到ViewModel。我能够在UI更改时成功更新ViewModel,反之亦然。然而,我似乎不明白PropertyChangedEventHandler中使用的"PropertyName"有什么用,因为无论我放在那里什么,它都会一直起作用。我不知道我是否已经把事情搞混了,因为我读了很多关于体系结构模式(MVP、MVC、MVVM和MVP-VM(这就是我现在试图做的))的文章。
以下是相关代码的一部分:
ViewModel
public class AdditionViewModel:INotifyPropertyChanged
{
private string augend;
public string Augend
{
get { return augend; }
set {
if(augend != value)
{
augend = value;
OnPropertyChanged(new PropertyChangedEventArgs("ugend"));
}
}
}
private string addend;
public string Addend
{
get { return addend; }
set {
if (addend != value)
{
addend = value;
OnPropertyChanged(new PropertyChangedEventArgs("ddend"));
}
}
}
private string answer;
public string Answer
{
get { return answer; }
set {
if(answer != value)
{
answer = value;
OnPropertyChanged(new PropertyChangedEventArgs("nswer"));
}
}
}
public AdditionClass additionClass;
public AdditionViewModel(AdditionClass _additionClass)
{
additionClass = _additionClass;
}
public void Add()
{
//Some verifications first before inserting the value to the model class
this.Augend = "1";//Testing for from code to UI binding
additionClass.Augend = Double.Parse(Augend);
additionClass.Addend = Double.Parse(Addend);
//Somewhere here should implement the compute but since addition is a very simple task, no methods were called;
Answer = additionClass.Answer.ToString();
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
MessageBox.Show(e.PropertyName);
handler(this, new PropertyChangedEventArgs(e.PropertyName));
}
}
}
形式:
private void Form1_Load(object sender, EventArgs e)
{
additionPresenter = new Presenter.AdditionPresenter(new ViewModel.AdditionViewModel(new Model.AdditionClass()));
additionViewModelBindingSource.DataSource = additionPresenter.additionViewModel;
}
private void button1_Click(object sender, EventArgs e)
{
additionPresenter.AddButtonClick();
}
演示者:
public AdditionPresenter(AdditionViewModel _additionViewModel)
{
additionViewModel = _additionViewModel;
}
public void AddButtonClick()
{
additionViewModel.Add();
}
设计器自动生成的代码之一(绑定在UI上):
//
// textBox1
//
this.textBox1.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.additionViewModelBindingSource, "Addend", true));
this.textBox1.Location = new System.Drawing.Point(24, 41);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(100, 20);
this.textBox1.TabIndex = 0;
正如在ViewModel上可以看到的那样,我省略了setters中每个PropertyName开头的所有"A",但应用程序仍在工作。很抱歉粘贴了太长的代码。我似乎找不到比向您展示实现
INotifyPropertyChanged
不是数据绑定所必需的,但它支持双向数据绑定
事实上,如文档中所述:INotifyPropertyChanged接口用于通知客户端(通常是绑定客户端)属性值已更改
在简单(单向)数据绑定中,当您更改控件的绑定属性时,值会推送到对象的绑定属性中,而不需要INotifyPropertyChanges
。
但如果没有INotifyPropertyChanged
,如果您使用代码更改对象的绑定属性的值,则新值不会推入控件的绑定属性。
在PropertyChanged事件中有错误的属性名称,为什么我仍然有双向数据绑定
事实上,正如Fabio在评论中提到的那样,这是因为使用BindingSource
作为数据源。
当使用CCD_ 5作为数据绑定的数据源时,对象实现INotifyPropertyChanged
并引发PropertyChaned
事件(即使属性名称为空或错误)就足够了,然后BindingSource
(实际上是其内部BindingList<T>
)订阅PropertyChaned
事件,当收到该事件时,它会检查您是否没有传递正确的属性名称,或者如果您传递了空的属性名称时,它将调用ResetBindings()
,从而导致控件绑定到BindingSource
以重新读取列表中的所有项目并刷新其显示的值。PropertyChanged
中的正确名称会导致双向数据绑定的正常行为,也会导致在e.PropertyDescriptor
中引发具有正确属性的ListChanged
事件。