INotifyPropertyChanged - 更改 PropertyName 没有效果
INotifyPropertyChanged - Changing PropertyName Causes No Effect
我正在尝试将我的 Winforms UI 绑定到我的 ViewModel。我能够在 UI 更改时成功更新我的 ViewModel,反之亦然。但是,我似乎无法理解 PropertyChangedEventHandler 中使用的 "PropertyName" 有什么用,因为无论我放在那里什么,它都会一直有效。我不知道我是否已经把事情搞混了,因为我已经阅读了很多关于架构模式的文章(MVP、MVC、MVVM 和 MVP-VM(这是我现在尝试做的))。
相关代码部分如下:
视图模型
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();
}
Designer 自动生成的代码之一(绑定到 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 上看到的那样,我在 setter 中省略了每个 PropertyName 开头的所有 "A",但应用程序仍在运行。
很抱歉粘贴了很长的代码。我似乎找不到比向您展示实现更好的解释
INotifyPropertyChanged
不是数据绑定所必需的,但它启用双向数据绑定。
事实上,如文档中所述:INotifyPropertyChanged 接口用于通知客户端(通常是绑定客户端)属性 值已更改。
在简单(单向)数据绑定中,当您更改控件的绑定 属性 时,值将推入对象的绑定 属性 并且不需要 INotifyPropertyChanges
.
但是如果没有 INotifyPropertyChanged
,如果您使用代码更改对象的绑定 属性 的值,新值不会推送到控件的绑定 属性.
在 PropertyChanged 事件中有错误的 属性 名称为什么我仍然有双向数据绑定?
事实上,这是因为使用 BindingSource
作为数据绑定的来源,正如 在评论中提到的。
当使用 BindingSource
作为数据绑定的数据源时,您的对象足以实现 INotifyPropertyChanged
并引发 PropertyChaned
事件(即使 [=47 为空或错误) =] 名称)然后是 BindingSource
(实际上是它的内部 BindingList<T>
)subscribes for PropertyChaned
event and when received the event it checkes if you didn't passed a correct property name or if you passed empty property name it the will call ResetBindings()
,结果导致绑定到 BindingSource
的控件重新读取列表中的所有项目并刷新他们的显示值。
PropertyChanged
中的正确名称会导致双向数据绑定的正常行为,还会导致在 e.PropertyDescriptor
.
中使用正确的 属性 引发 ListChanged
事件
我正在尝试将我的 Winforms UI 绑定到我的 ViewModel。我能够在 UI 更改时成功更新我的 ViewModel,反之亦然。但是,我似乎无法理解 PropertyChangedEventHandler 中使用的 "PropertyName" 有什么用,因为无论我放在那里什么,它都会一直有效。我不知道我是否已经把事情搞混了,因为我已经阅读了很多关于架构模式的文章(MVP、MVC、MVVM 和 MVP-VM(这是我现在尝试做的))。
相关代码部分如下:
视图模型
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();
}
Designer 自动生成的代码之一(绑定到 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 上看到的那样,我在 setter 中省略了每个 PropertyName 开头的所有 "A",但应用程序仍在运行。 很抱歉粘贴了很长的代码。我似乎找不到比向您展示实现更好的解释
INotifyPropertyChanged
不是数据绑定所必需的,但它启用双向数据绑定。
事实上,如文档中所述:INotifyPropertyChanged 接口用于通知客户端(通常是绑定客户端)属性 值已更改。
在简单(单向)数据绑定中,当您更改控件的绑定 属性 时,值将推入对象的绑定 属性 并且不需要 INotifyPropertyChanges
.
但是如果没有 INotifyPropertyChanged
,如果您使用代码更改对象的绑定 属性 的值,新值不会推送到控件的绑定 属性.
在 PropertyChanged 事件中有错误的 属性 名称为什么我仍然有双向数据绑定?
事实上,这是因为使用 BindingSource
作为数据绑定的来源,正如
当使用 BindingSource
作为数据绑定的数据源时,您的对象足以实现 INotifyPropertyChanged
并引发 PropertyChaned
事件(即使 [=47 为空或错误) =] 名称)然后是 BindingSource
(实际上是它的内部 BindingList<T>
)subscribes for PropertyChaned
event and when received the event it checkes if you didn't passed a correct property name or if you passed empty property name it the will call ResetBindings()
,结果导致绑定到 BindingSource
的控件重新读取列表中的所有项目并刷新他们的显示值。
PropertyChanged
中的正确名称会导致双向数据绑定的正常行为,还会导致在 e.PropertyDescriptor
.
ListChanged
事件