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");
}
}
}
