winform class 中所有子属性的 propertyChanged 更新问题
Issue of propertyChanged update for all subproperty in a class in winform
我实现了一个模型 class 并希望在修改对象时为所有子属性引发 PropertyChanged 事件。但是我发现它不起作用。当我按下按钮时,标签的文本不是 changed.Does 我错过了什么?我从 MSDN 得到这个 -"The PropertyChanged event can indicate all properties on the object have changed by using either null or String.Empty as the property name in the PropertyChangedEventArgs."
平台是 .net framework 4.0 和 VS2015
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Model = new Model()
{
data = new User()
{
Name = "test"
}
};
label1.DataBindings.Add("Text", Model.data, "Name", false, DataSourceUpdateMode.OnPropertyChanged);
}
private Model model;
public Model Model
{
get
{
return this.model;
}
set
{
model = value;
}
}
private void button1_Click(object sender, EventArgs e)
{
User temp = new User()
{
Name = "test1"
};
Model.data = temp;
}
}
public class NotifyPropertyChanged : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField<T>(ref T field, T value, string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
OnPropertyChanged(null);
return true;
}
}
public class Model : NotifyPropertyChanged
{
private User m_data;
public User data
{
get { return m_data; }
set
{
SetField(ref m_data, value,"data");
}
}
}
public class User : NotifyPropertyChanged
{
private string name;
public string Name
{
get { return this.name; }
set
{
SetField(ref name, value, "Name");
}
}
private string tel;
public string Tel
{
get { return this.tel; }
set
{
SetField(ref tel, value, "Tel");
}
}
}
您的问题是您对 Model.data
的绑定,但后来为它分配了一个新值。
因此,绑定监视的实例不再被使用。
您有 2 个选择:
第一个:不要创建新的 User
,只需将其更改为 Name
:
private void button1_Click(object sender, EventArgs e)
{
Model.data.Name = "test1";
}
或者,如果您确实需要支持两种情况(创建和分配),那么您必须将绑定更改为 Model
并从 data.Name
:[=25= 中获取文本]
label1.DataBindings.Add("Text", Model, "data.Name", false,
DataSourceUpdateMode.OnPropertyChanged);
和Model
中User
属性的set
部分到此:
set
{
SetField(ref m_data, value, "data");
this.data.PropertyChanged += (sender, args) => this.OnPropertyChanged("data");
}
因此,这将在数据上创建一个 PropertyChanged
,如果 data.Name
已更改,那么如果 data
属性 本身已 set
我实现了一个模型 class 并希望在修改对象时为所有子属性引发 PropertyChanged 事件。但是我发现它不起作用。当我按下按钮时,标签的文本不是 changed.Does 我错过了什么?我从 MSDN 得到这个 -"The PropertyChanged event can indicate all properties on the object have changed by using either null or String.Empty as the property name in the PropertyChangedEventArgs." 平台是 .net framework 4.0 和 VS2015
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Model = new Model()
{
data = new User()
{
Name = "test"
}
};
label1.DataBindings.Add("Text", Model.data, "Name", false, DataSourceUpdateMode.OnPropertyChanged);
}
private Model model;
public Model Model
{
get
{
return this.model;
}
set
{
model = value;
}
}
private void button1_Click(object sender, EventArgs e)
{
User temp = new User()
{
Name = "test1"
};
Model.data = temp;
}
}
public class NotifyPropertyChanged : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField<T>(ref T field, T value, string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
OnPropertyChanged(null);
return true;
}
}
public class Model : NotifyPropertyChanged
{
private User m_data;
public User data
{
get { return m_data; }
set
{
SetField(ref m_data, value,"data");
}
}
}
public class User : NotifyPropertyChanged
{
private string name;
public string Name
{
get { return this.name; }
set
{
SetField(ref name, value, "Name");
}
}
private string tel;
public string Tel
{
get { return this.tel; }
set
{
SetField(ref tel, value, "Tel");
}
}
}
您的问题是您对 Model.data
的绑定,但后来为它分配了一个新值。
因此,绑定监视的实例不再被使用。
您有 2 个选择:
第一个:不要创建新的 User
,只需将其更改为 Name
:
private void button1_Click(object sender, EventArgs e)
{
Model.data.Name = "test1";
}
或者,如果您确实需要支持两种情况(创建和分配),那么您必须将绑定更改为 Model
并从 data.Name
:[=25= 中获取文本]
label1.DataBindings.Add("Text", Model, "data.Name", false,
DataSourceUpdateMode.OnPropertyChanged);
和Model
中User
属性的set
部分到此:
set
{
SetField(ref m_data, value, "data");
this.data.PropertyChanged += (sender, args) => this.OnPropertyChanged("data");
}
因此,这将在数据上创建一个 PropertyChanged
,如果 data.Name
已更改,那么如果 data
属性 本身已 set