Umstellung auf PropertyChanged
Die Components arbeiten nutzen jetzt das Event PropertyChanged um Änderungen an Properties zu kommunizieren.
Sie implementieren dazu das Standard-Interface INotifyPropertyChanged
.
Die bisher verwendeten Events, welche für jedes einzelne Component-Property sparat generiert wurden, entfallen. Wenn eigener Code existiert, der mit diesen Events arbeitet, muss dieser angepasst werden.
Im folgenden werden einige Situationen beschrieben.
Die Beispiele verwenden eine Component cdArticle
mit den Properties sArticleID
und sArticleName
.
Event-Handler umstellen
Bisher gab es die folgenden Events
public event EventArgs sArticleIDChanged;
public event EventArgs sArticleNameChanged;
Diese wurden auf die folgende Weise verwendet:
// anhängen des Event-Handlers
oArticle.sArticleIDChanged += OnArticleIDHasChanged;
// Event-Handler-Methode
protected void OnArticleIDHasChanged(object sender, EventArgs args)
{
// Code für geänderte Artikel-ID
}
// Event mit Lambda-Expression
oArticle.sArticleNameChanged += (sender, args) =>
{
// Code für geänderte Artikel-Bezeichnung
};
Jetzt gibt es nur noch ein Event, welches in der Basis-Klasse DevFrameworkBaseObject
implementiert ist.
public event PropertyChangedEventArgs PropertyChanged;
Dieses wird auf folgende Weise verwendet:
// anhängen des Event-Handlers
oArticle.PropertyChanged += OnArticleIDHasChanged;
// Event-Handler-Methode
protected void OnArticleIDHasChanged(object sender, PropertyChangedEventArgs args)
{
if (args.IsProperty(nameof(IcdArticle.sArticleID)))
{
// Code für geänderte Artikel-ID
}
}
// Event mit Lambda-Expression
oArticle.sArticleNameChanged += (sender, args) =>
{
if (args.IsProperty(nameof(oArticle.sArticleName)))
{
// Code für geänderte Artikel-Bezeichnung
}
};
Aufrufe von Fire-Methoden
Alter Code:
this.FiresArticleIDChanged();
this.FiresArticleNameChanged();
Neuer Code:
this.FirePropertyChanged(nameof(this.sArticleID));
this.FirePropertyChanged(nameof(this.sArticleName));
Muss man viele dieser Aufrufe ersetzen, kann man dafür im Code-Editor die Funktion Find/Replace verwenden.
- Suche mir Regular Expression:
this.Fire(?<prop>(?!Property)\w+)Changed\s*\(\s*\)
- Ersetzen durch:
this.FirePropertyChanged(nameof(this.${prop}))
StateChanged, IsModifiedChanged
Die Component-Properties State
und IsModified
, werden jetzt ebenfalls über PropertyChanged behandelt.
Die virtuellen Methoden OnStateChanged
und OnIsModifiedChanged
sind entfallen. Stattdessen kann diese Logik in die neue Methode OnPropertyChanged
verschoben werden.
Alter Code:
protected override void OnStateChanged()
{
// Status hat sich geändert
}
protected override void OnIsModifiedChanged()
{
// IsModified hat sich geändert
}
Neuer Code:
protected override void OnPropertyChanged(string propertyName)
{
// Base-Aufruf ist wichtig !!!
base.OnPropertyChanged(propertyName);
if (propertyName == nameof(this.State))
{
// Status hat sich geändert
}
if (propertyName == nameof(this.IsModified))
{
// IsModified hat sich geändert
}
}
Neuer Code für Event-Handler:
// anhängen des Event-Handlers
oArticle.PropertyChanged += OnArticleStateChanged;
// Event-Handler-Methode
protected void OnArticleStateChanged(object sender, PropertyChangedEventArgs args)
{
// Die Prüfung auf PropertyName == null macht hier keinen Sinn
if (args?.PropertyName == nameof(this.State))
{
// Status hat sich geändert
}
}
Reflection
Caution
Wenn die alten Changed-Events per Reflection angesprochen wurden, dann muss das gezielt umgebaut werden. Diese Fälle werden nicht durch den Compiler gefunden.
Mit einer Volltext-Suche nach folgendem Regulären Ausdruck könnten potentielle Stellen leicht gefunden werden:
\bEventInfo\b
Beispiel für einen problematischen Code:
System.Reflection.EventInfo oChangedEventInfo = this.oTarget.GetType().GetEvent(sPropertyNameP + "Changed");
if (oChangedEventInfo != null)
{
oChangedEventInfo.AddEventHandler(this.oTarget, oXmlPropertyInfo.oChangedEventHandler);
}