- Abbiamo introdotto il pattern Model View ViewModel partendo dai concetti di base;
- Ci siamo spostati in uno scenario un po’ più complesso;
- Abbiamo piacevolmente divagato su alcuni punti che sono emersi;
- essere in grado di modificare un indirizzo;
- essere in grado di eliminare un indirizzo;
- come tenere traccia dell’elemento selezionato nella lista degli indirizzi?
- come visualizzare i dati dell’elemento selezionato?
- come gestire un’azione, la cancellazione in questo caso?
Tenere traccia di quale sia l’indirizzo selezionato è un’operazione relativamente banale:
Anche se ci pone di fronte ad una prima decisione: chi è responsabile di tenere traccia di quale sia l’elemento selezionato?private AddressViewModel _selectedAddress = null; public AddressViewModel SelectedAddress { get { return this._selectedAddress; } set { if( value != this.SelectedAddress ) { this._selectedAddress = value; this.OnPropertyChanged( () => this.SelectedAddress ); } } }
- PersonViewModel?
- o MainViewModel?
Le modifiche da apportare allo xaml sono altrettanto banali:
Ci limitiamo a chiedere alla ListView di tracciare quale sia l’lemento corrente mettendo in binding la proprietà SelectedItem con la nostra proprietà SelectedAddress.<ListView Grid.ColumnSpan="2" Grid.Row="4" Margin="12" ItemsSource="{Binding Path=Person.Addresses}" SelectedItem="{Binding Path=SelectedAddress}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
Visivamente a questo punto non è cambiato nulla ma se mettiamo un breakpoint sul setter della nostra proprietà al variare dell’elemento selezionato il motore di binding viene da noi a impostare il nuovo valore.
Naturalmente il binding è bidirezionale quindi possiamo preimpostare un SelectedAddress e vedere che la ListView si adegua di conseguenza:
this.SelectedAddress = this.Person.Addresses.FirstOrDefault();
SelectedItem “reverse” binding
Ora che abbiamo un elemento selezionato possiamo introdurre nella nostra vista master-details la porzione di UI per l’editing e ringraziare il motore di databinding di Wpf per averci regalato cotanta potenza:
Potenza che già a designtime, visto che per ora le cose sono molto semplici, ci fa capire che siamo sulla strada giusta:<TextBox Height="23" HorizontalAlignment="Stretch" Text="{Binding Path=SelectedAddress.Street, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Grid.Column="1" Grid.Row="6" /> <TextBlock HorizontalAlignment="Right" Text="Number:" VerticalAlignment="Top" Grid.Row="7" /> <TextBox Height="23" HorizontalAlignment="Stretch" Text="{Binding Path=SelectedAddress.Number, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Grid.Column="1" Grid.Row="7" /> <TextBlock HorizontalAlignment="Right" Text="City:" VerticalAlignment="Top" Grid.Row="8" /> <TextBox Height="23" HorizontalAlignment="Stretch" Text="{Binding Path=SelectedAddress.City, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Grid.Column="1" Grid.Row="8" />
A runtime abbiamo la conferma definitiva:
Cambiando la selezione automaticamente il nostro dettaglio si aggiorna, ma non solo, scrivendo qualcosa nel campo “City”, ad esempio, il valore viene riflesso, real-time, anche nella ListView sempre grazie al motore di DataBinding.
Adesso che abbiamo un elemento selezionabile, tracciabile e modificabile non ci resta che renderlo anche cancellabile… ma direi che oggi ho scritto un’altra volta fin troppo :-)
Sorgenti aggiornati: Mvvm.Application-1.2.zip
.m
Imported comment, original author: raffaeu
ReplyDeleteMauro avrei una domandina tecnica su MVVM e non trovo risposta.
Senza usare Prism come orchestri la navigazione?
Con MVP e WinForm io usavo il navigator, che si istanziava con l' avvio dell' applicazione.
Con MVC ho la controller Factory e il global.asax ma con MVVM cosa consigli?
Magari hai gia' scritto qualcosa a riguardo? Scusa ma il mio cervello non ha tutti questi neuroni per memorizzare la miriade di inputs che trova nel tuo blog. :-)
Imported comment, original author: Mauro Servienti
ReplyDeleteio mi affido al MessageBroker ma è un argomento vasto e complesso che meriterebbe ben più di un post.
Imported comment, original author: raffaeu
ReplyDeleteah ... ho capito. Questo week-end allora ci gioco usando il tuo framework.
Per ora grazie.
Imported comment, original author: Mauro D.
ReplyDeleteHo un dubbio sul tuo modo di usare il modello nel viewmodel... Tu copi le proprietà del modello su quelle del viewmodel e così eviti di avere INotifyPropertyChanged sul modello... Avevo provato anche io a fare così ma poi quando arrivavo al salvataggio dell'entità con NHibernate.. BOOM! Dovevo ricreare l'entità dalle proprietà del viewmodel e quando arrivavo a una proprietà IList NHibernate rompeva le scatole.
Imported comment, original author: _Daedalus
ReplyDeleteStupendi questi post sul M-V-VM! Veramente ben fatti!
Mauro scrivi benissimo, e sai esporre l'argomento in modo molto terra-terra senza mancare di nulla.
Io che sono passato a WPF da poco sto riuscendo, grazie a te, a strutturare un'applicazione usando il nostro amico ;) come linea guida, grazie!
Ma... sbaglio o manca un'ultimo post? =P
c'è una remota possibilità che questa serie sul M-V-VM vada oltre gli argomenti previsti?
Imported comment, original author: Mauro Servienti
ReplyDeleteCiao _Daedalus,
innanzitutto grazie, si manca un ultimo post (in realtà 2) che è in coda da tempo ma in questo periodo sono troppo preso per poterlo finire come si deve, e si credo proprio che questa serie non finirà così ;-)
.m