问题
When you implement the INotifyPropertyChanged interface, you're responsible for calling the PropertyChanged event each and everytime a property is updated in the class.
This typically leads to the following code :
public class MyClass: INotifyPropertyChanged
private bool myfield;
public bool MyField
{
get { return myfield; }
set
{
if (myfield == value)
return;
myfield = value;
OnPropertyChanged(new PropertyChangedEventArgs("MyField"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler h = PropertyChanged;
if (h != null)
h(this, e);
}
}
That is 12 lines per property.
It would be so much simpler if one was able to decorate automatic properties like this :
[INotifyProperty]
public double MyField{ get; set; }
But unfortunately this is not possible (see this post on msdn for example)
How can I reduce the amount of code needed per property?
回答1:
Actually, it's only 3-4 lines per property; the other lines are amortized over all "notifying" properties:
class Person : INotifyPropertyChanged
{
#region INotifyPropertyChanged: Shared bit
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
#endregion
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
if (_firstName == value)
return;
_firstName = value;
OnPropertyChanged(new PropertyChangedEventArgs("FirstName"));
}
}
// Ditto for other properties
}
You could try something like the following, which shares some more of the load:
private string _firstName;
public string FirstName
{
get { return _firstName; }
set { SetNotifyingProperty("FirstName", ref _firstName, value); }
}
private void SetNotifyingProperty<T>(string propertyName,
ref T field, T value)
{
if (value.Equals(field))
return;
field = value;
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
回答2:
What I do for now is that I write this in my class :
//AUTOGENERATE INotifyProperty
private bool myfield;
And I wrote a small tool which generate all the needed property code in a partial class. This is by no way an elegant solution, but it works :)
回答3:
It makes most sense to outsource.
Write a class ( ObservableObject) with the following code:
class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
All classes derived from this class can access the method, thanks to protected.
Example:
class Example : ObservableObject
{
//propfull
private string name;
public string Name
{
get {return name;}
set
{
name = value;
OnPropertyChanged(nameof(Name));
}
}
}
来源:https://stackoverflow.com/questions/488587/whats-the-best-way-to-call-inotifypropertychangeds-propertychanged-event