Skip to content

Forum

Please or Register to create posts and topics.

vediamo se ho capito MVVM...

Ho una classe cliente con le sue proprietà Nome, Cognome, ecc

poi ho una window con i vari textbox

normalmente avrei istanziato cliente nel code behind della window, impostato il datacontext sul istanza di cliente e messo nello xaml in binding i vari textbox con le varie proprietà di cliente..

volendo passare a MVVM se ho capito bene devo creare una classe clienteViewModel che mi espone le stesse proprietà di cliente, istanzia cliente al suo interno e i vari getter mi ritornano i valori delle proprietà di cliente

es.

Property Nome as string
Get
return Cliente.Nome
End Get

quindi nel code behind della window instanzio clienteViewModel e lo uso come datacontext.

in questo caso posso lasciare il model (cliente) e la View  puliti, cioè senza codice (o lo stretto necessario nella view) e tutto l'eventuale codice lo posso mettere nel Viewmodel..

se ad esempio voglio che quando imposto il Comune automaticamente il programma imposti CAP e Provincia prendendoli da una lista, questo codice lo metto nel ViewModel

o anche se mi serve una proprietà "complessa" come per esempio una che mi ritorni l'indirizzo completo formattato (Nome Cognome Via x, y Cap Comune PROV), pure questa la metto nel ViewModel così il model resta pulito (solo dati)

Ho capito giusto?

p.s. in questo caso il notifypropertychange mi basta implementarlo solo nel viewmodel x aggiornare automaticamente i controlli visto che cliente viene caricato solo all'inizio da disco e modificato solo tramite la viewmodel?

Direi che fondamentalmente si hai capito bene, però nel viewmodel io metto un istanza di Cliente e all'interno di Cliente implemento INotifyPropertyChanged in modo che le property reagiscono correttamente quando attacco tali property alle textbox dal Viewmodel onde evitare di dover generare 2 classi diverse per lo stesso uso.

Per mio difetto personale, anche tutte le property aggiuntive (indirizzo completo, ecc.) le implemento nella classe Cliente e non nel Viewmodel, il ViewModel è un oggetto che parla con la view e con il model (dal suo nome) e contiene tutte le istanze degli oggetti del model (che possono essere tanti) che utilizzi in una window, ad esempio, nel viewmodel di una Lista clienti, hai bisogno di una ObservableCollection<Cliente> per la lista e di un ClienteCorrente da collegare all'elemento selezionato se vuoi poi chiamare la finestra del dettaglio cliente per il Cliente corrente della lista.

Ti ho confuso a sufficienza?

Chiedi pure tutte le delucidazioni che vuoi

 

Marco75 has reacted to this post.
Marco75

Riporto la mia esperienza sul commento di Sabrina

All'inizio ero partito ad usare solo ClienteSelezionato, poi ho aggiunto ClienteCorrente per distinguerlo dal primo.

Ma da qui ho cominciato a fare confusione coi i due termini e ad incasinare il codice.

Quindi, per buona pratica, ora uso di base sempre una lista per i Selezionati (anche se inizialmente a prima vista potrebbe essere solo uno) e un oggetto per il Corrente.

 

 

 

 

 

sabrina_c and Marco75 have reacted to this post.
sabrina_cMarco75

Grazie a entrambi.. ora credo di avere le idee un po' più chiare,

io immaginavo il viewmodel come una classe che "riveste" il model (instanziandolo al suo interno) e ne espone le singole proprietà, per ogni model.proprietà c'è una corrispondente viewmodel.proprietà(che va a leggere/scrivere in model.proprietà).

invece è più simile al "vecchio" code behind della view..
instanzia il model ed espone il model stesso (viewmodel.model)
diciamo che serve "solo" per spostare tutto il codice al di fuori della view così da separare e rendere indipendenti il lavoro del designer (che si occupa della view) e del programmatore (che si occupa del viewmodel e che dovrà fornire al designer solo i nomi delle proprietà da collegare nella view).

forse stavolta l'ho capita  🙂

 

ci ho provato ma qualcosa non va...

creo la classe viewmodel che instanzia model e ne espone la proprietà

nel code behind:

Public Property ClienteViewModel As New ClienteViewModel
datacontext=me

e fin qui tutto funziona

se nello xaml scrivo:

<StackPanel >
<TextBox Width="600" Text="{Binding Path=ClienteViewModel.Cliente.Nickname}" />
</StackPanel>

Funziona,
ma se invece imposto ClienteViewModel come DataContext di tutto lo stackpanel che ospita i vari textbox..

<StackPanel DataContext="ClienteViewModel">
<TextBox Width="600" Text="{Binding Path=Cliente.Nickname}" />
</StackPanel>

non funziona più.. con questo errore di binding

BindingExpression path error: 'Cliente' property not found on 'object' ''String' (HashCode=-1467934314)'. BindingExpression:Path=Cliente.Nickname; DataItem='String' (HashCode=-1467934314); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String')

perché object 'string' ?? non dovrebbe far riferimento a ClienteViewModel ?

Non sono sicuro del codice che hai scritto, comunque

<StackPanel DataContext="ClienteViewModel"> // ClienteViewModel qui e' una string 🙂

dovrebbe essere:

<StackPanel DataContext="{Binding ClienteViewModel}">

 

Assegnare però il datacontext allo StackPanel non credo abbia molto senso, anche se si puo' fare.

Il datacontext lo assegnerei alla Window (o comunque al controllo "radice") che contiene lo StackPanel.

Poi magari nel tuo caso va bene così.

ammazza al {binding}.. ecco perché mi dava quell' errore

assegnavo il Datacontext allo StackPanel perché ci avevo messo dentro solo la parte che gestisce il cliente selezionato, lasciando la lista dei clienti nel code behind..

ora ho messo tutto nel viewmodel e assegnato alla radice ( una Page nel mio caso) e funziona benissimo.

grazie delle dritte !!