C# Language
Interfaccia INotifyPropertyChanged
Ricerca…
Osservazioni
L'interfaccia INotifyPropertyChanged
è necessaria ogni volta che è necessario per rendere la classe segnalare le modifiche che si verificano alle sue proprietà. L'interfaccia definisce un singolo evento PropertyChanged
.
Con XAML Binding l'evento PropertyChanged
è cablato automaticamente, quindi è necessario implementare l'interfaccia INotifyPropertyChanged sul proprio modello di vista o sulle classi di contesto dati per lavorare con XAML Binding.
Implementazione di INotifyPropertyChanged in C # 6
L'implementazione di INotifyPropertyChange
può essere soggetta a errori, poiché l'interfaccia richiede di specificare il nome della proprietà come stringa. Per rendere l'implementazione più solida, è possibile utilizzare un attributo CallerMemberName
.
class C : INotifyPropertyChanged
{
// backing field
int offset;
// property
public int Offset
{
get
{
return offset;
}
set
{
if (offset == value)
return;
offset = value;
RaisePropertyChanged();
}
}
// helper method for raising PropertyChanged event
void RaisePropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
// interface implemetation
public event PropertyChangedEventHandler PropertyChanged;
}
Se hai diverse classi che implementano INotifyPropertyChanged
, potresti trovare utile rifattorizzare l'implementazione dell'interfaccia e il metodo helper alla classe base comune:
class NotifyPropertyChangedImpl : INotifyPropertyChanged
{
protected void RaisePropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
// interface implemetation
public event PropertyChangedEventHandler PropertyChanged;
}
class C : NotifyPropertyChangedImpl
{
int offset;
public int Offset
{
get { return offset; }
set { if (offset != value) { offset = value; RaisePropertyChanged(); } }
}
}
InotifyPropertyChanged con metodo Set generico
La classe NotifyPropertyChangedBase
seguito definisce un metodo Set generico che può essere chiamato da qualsiasi tipo derivato.
public class NotifyPropertyChangedBase : INotifyPropertyChanged
{
protected void RaisePropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
public event PropertyChangedEventHandler PropertyChanged;
public virtual bool Set<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (Equals(field, value))
return false;
storage = value;
RaisePropertyChanged(propertyName);
return true;
}
}
Per utilizzare questo metodo Set generico, è sufficiente creare una classe che derivi da NotifyPropertyChangedBase.
public class SomeViewModel : NotifyPropertyChangedBase
{
private string _foo;
private int _bar;
public string Foo
{
get { return _foo; }
set { Set(ref _foo, value); }
}
public int Bar
{
get { return _bar; }
set { Set(ref _bar, value); }
}
}
Come mostrato sopra, puoi chiamare Set(ref _fieldName, value);
nel setter di una proprietà e genererà automaticamente un evento PropertyChanged se necessario.
È quindi possibile registrarsi all'evento PropertyChanged da un'altra classe che deve gestire le modifiche alle proprietà.
public class SomeListener
{
public SomeListener()
{
_vm = new SomeViewModel();
_vm.PropertyChanged += OnViewModelPropertyChanged;
}
private void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
Console.WriteLine($"Property {e.PropertyName} was changed.");
}
private readonly SomeViewModel _vm;
}