L’interface INotifyPropertyChanged à beau faire des heureux, elle peut aussi être à l’origine de pas mal d’erreurs et surtout d’un bon gros StackOverflowException pour les moins prudents. Voici donc, “the” erreur de débutant à ne pas faire avec WPF et l’interface INotifyPropertyChanged.
Ne jamais écrire un code comme celui-ci :
Vb:
Imports System.ComponentModel Public Class MaClass Implements INotifyPropertyChanged Private _Mapropriete As String Public Property Mapropriete() As String Get Return Me._Mapropriete End Get Set(ByVal value As String) Me._Mapropriete = value Me.RaisePropertyChanged("Mapropriete") End Set End Property #Region "INotifyPropertyChanged Members" Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged Private Sub RaisePropertyChanged(ByVal propertyName) RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName)) End Sub #End Region End Class
C#:
public class MaClass : INotifyPropertyChanged { private String _Mapropriete; public String Mapropriete { get { return this._Mapropriete; } set { this._Mapropriete = value; this.RaisePropertyChanged("Mapropriete"); } } #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(String propertyName) { if (this.PropertyChanged != null) { this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } #endregion }
Pourquoi?
Si votre propriété est a un DataBind sur un control et que celui-ci est à double sens, dès que ce control vas être changé, votre événement vas être déclenché… et si il est déclenché votre control va chercher à nouveau à se mettre à jour, et s’est parti pour un StackOverflowException! Boom!
Donc il faudra privilégier un code qui control si votre event doit être remonté.
Par exemple en changeant le code de ma propriété :
Vb
Public Property Mapropriete() As String Get Return Me._Mapropriete End Get Set(ByVal value As String) If (Me._Mapropriete <> value) Then Me._Mapropriete = value Me.RaisePropertyChanged("Mapropriete") End If End Set End Property
C#:
public String Mapropriete { get { return this._Mapropriete; } set { if ( this._Mapropriete != value) { this._Mapropriete = value; this.RaisePropertyChanged("Mapropriete"); } } }