martedì 7 settembre 2010

WPF - Il default di un combo non viene impostato correttamente (PropertyChanged is NULL)

C# 4.0

Si verifica la seguente anomalia: dopo aver caricato una maschera WPF (binding ad una proprietà di tipo Coupon) con all’interno alcuni controlli tra i quali anche un combo, non si riesce ad impostare il combo con un determinato elemento.


Il combo ha come ItemSource una lista (CouponTypes) di oggetti di tipo CouponType, il quale oggetto a sua volta implementa l’interfaccia INotifyPropertyChanged, quindi riepilogando:


public class Coupon : INotifyPropertyChanged

{

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string propertyName)

{

if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

}

private CouponType _couponType;

/// <summary>
/// "CouponType": il tipo di coupon: Unspecified, Free, ValueFree, Fidelity, Serialized;
/// </summary>

public CouponType CouponType

{

get { return _couponType; }

set

{

if (value == _couponType) return;

_couponType = value;

OnPropertyChanged("CouponType");

}

}



}


public class CouponType : INotifyPropertyChanged

{

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string propertyName)

{

if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

}

/// <summary>
/// Gets or sets the code.
/// </summary>
/// <value>The code.</value>

public CouponTypeEnum Code

{

get { return _code; }

set

{

if (value == _code) return;

_code = value;

OnPropertyChanged("Code");

}

}

/// <summary>
/// Gets or sets the description.
/// </summary
/// <value>The description.</value>

public string Description

{

get { return _description; }

set

{

if (value == _description) return;

_description = value;

OnPropertyChanged("Description");

}

}
private CouponTypeEnum _code;

private string _description;

}


Al caricamento della maschera si crea un nuovo oggetto di tipo Coupon e si carica la collection di _couponTypes:

_coupon = new Coupon();
_couponTypes = ContextCommonService.LoadCouponTypes();

Quindi per impostare l’elemento di default si usa la seguente lambda expression :

Coupon.CouponType = CouponTypes.Find(item => item.Code == CouponTypeEnum.ValueFree);

Il risultato è che il combo non viene impostato correttamente perché (in debug) si nota che PropertyChanged è sempre NULL.

Alla fine si è quindi capito che PRIMA bisogna caricare la collection _couponTypes e DOPO inizializzare l’oggetto Coupon:

_couponTypes = ContextCommonService.LoadCouponTypes();
_coupon = new Coupon();