Articoli con tag Binding

INotifyPropertyChanged serve davvero? Sì! Ma le cose si fanno complicate…

Leggendo per caso il blog di Gianni Giaccaglini (http://blogs.wpfitalia.it/GianniGiaccaglini/archive/2011/09/08/Binding-ADO-tramite-classe-ad-hoc.aspx) riguardo il binding verso dataset, ho notato un capitolo, “INotifyPropertyChanged server davvero?” e mi sono ricordato di un problema simile (forse lo stesso) che mi è capitato tempo fa.
Iniziamo dal codice xaml e il datacontext:

<StackPanel>
    <TextBox Text="{Binding Path=PrimaProp}" />
    <TextBox Text="{Binding Path=PrimaProp}" />
    <TextBox Text="{Binding Path=SecondaProp}" />
    <TextBox Text="{Binding Path=SecondaProp}" />
    <Button Content="Cambia" Click="Button_Click" />
</StackPanel>

public class MyDataContext
{
    public string PrimaProp { get; set; }
    public string SecondaProp { get; set; }
}

Qualcuno noterà che MyDataContext (nel codebehind viene impostata un istanza come DataContext) non implementa INotifyPropertyChanged.
Modificando una textbox ci si aspetterebbe che le altre non cambino perchè non si notifica alla vista che la proprietà è stata cambiata… E invece tutto funziona!
Ai tempi pensai che l’engine di wpf fosse abbastanza intelligente da usare un oggetto binding uguale se viene scritto uguale in più parti… invece no Smile.
Se proviamo infatti a impostare via codice il binding (es: textbox1.SetBinding(TextBox.TextProperty, new Binding(“PrimaProp”))), con nuove istanze di Binding su diversi oggetti, continua ancora a funzionare.

Proviamo a cambiare la proprietà del datacontext da codice tramite il bottone con:
(this.DataContext as MyDataContext).SecondaProp=”modifica da codice”… NON FUNZIONA!

Non sapendo dove andare a parare, ho cercato con google, e infine ho trovato la soluzione indicata qui: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/9365bb6a-b411-4967-9a03-ae2a810fb215/

Sunto della soluzione:
– Se un oggetto CLR implementa INotifyPropertyChanged, è cura del developer lanciare l’evento NotifyPropertyChanged
– Se un oggetto CLR NON implementa INotifyPropertyChanged, il binding lavora sul TypeDescriptor dell’oggetto. Esso va a registrare alla modifica delle proprietà tramite PropertyDescriptor.AddValueChanged().

Quindi:
1) come far andare il codice precedente riguardo il bottone:
”semplice” (?!?) basta recuperare la PropertyDescriptor dell’oggetto e impostare così la proprietà:
var propertyDescriptor = TypeDescriptor.GetProperties(this.DataContext).Find(“SecondaProp”, false);
propertyDescriptor.SetValue(this.DataContext, “ModificaDaCodice”);

2) come far smettere di andare il precedente esempio:
Implementiamo l’interfaccia INotifyPropertyChanged e propaghiamo l’evento solo per PrimaProp. Questa funziona, ma SecondaProp no Smile.

Performance (mentre l’ho fatto ho sentito l’esigenza di un altro post)

Se eseguo il codice nel thread UI, le performance sono molto simili.
Se eseguo il codice in un altro thread, l’utilizzo di INotifyPropertyChanged risulta più rapido rispetto a PropertyDescriptor.

Conclusioni:

Data la flessibilità e la maggior facilità implementativa, la mia preferenza ricade indubbiamente a INotifyPropertyChanged. Le performance inoltre sembrerebbero avvalorare tale scelta. Quindi Me.NofifyPropertyChanged(“you”);

Pubblicità

,

Lascia un commento

Binding del controllo Slider in Silverlight4

Oggi mi sono imbattuto in questo fastidioso problema: avete mai usato uno slider? se sì, avete mai messo in Binding le dependency property Minimum e Maximum oltre che a Value? vi è andato al primo colpo? fortunati …

Il problema principale è l’ordine con cui si imposta. In ordine si dovranno impostare i binding per:

  • Maximum
  • Minimum
  • Value

Se così non fate, Silverlight si perde qualcosa per strada Smile. Una corretta dichiarazione è quindi:

<Slider Maximum="{Binding Path=Max}" Minimum="{Binding Path=Min}" Value="{Binding Path=Value, Mode=TwoWay}" />

Se, come me, provate a impostare prima Minimum e poi Maximum, noterete che il valore di Maximum non viene impostato (anzi, se debuggate Maximum verrà impostato a zero).

Spero non perdiate tutto il tempo che io ho perso per capire il problema.

ps: in WPF4 è order independent.

,

Lascia un commento