Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Sempre per notificare la modifica del valore di una proprietà, se hai paura di sbagliare utilizzando una stringa, se stai usando MVVM Light (che anch'io ti consiglio) puoi scrivere:
this.musicList.Items.Add(new MusicItem());//Item di prova
}
Assegni correttamente al DataContext della ListView un'istanza di ViewMusic. (poi scoprirai che si sono dei metodi migliori)
Sbagli il passaggio successivo: non è dal "code behind" della View che aggiungi gli elementi. La ListView ha una proprietà ItemsSource, se tu assegna ad essa una proprietà IEnumerable, la ListView prende da li gli elementi e "se li auto-aggiunge".
Nel tuo specifico caso mettiamo che tua abbia in ViewMusic una proprietà chiamata Songs di tipo List<MusicItem>.
Nello XAML della ListView scriverai ItemsSource={Binding Path=Songs}.
Cosa succede: va a cercare nel DataContext della ListView la proprietà Songs, prende tutto ciò che trova dentro, e per ogni oggetto aggiunge un ListViewItem con i dati dentro, fa tutto da solo.
La logica che tasx definisce di business, ossia quella che manipola i dati ed esegue altre operazioni, sta tutta nel ViewModel.
A questo punto di parlerà di comandi: avrai una proprietà di tipo RelayCommand (una void in sostanza) che verrà assegnata al Click di un Button: clicki il Button -> il comando viene invocato, il tuo comando potrebbe far apparire la finestra di aggiunta/modifica del model, o una messagebox per la conferma di eliminazione.
Sei hai dubbi chiedi pure!
EDIT: ti ho creato un esempio al volo che mostra anche l'utilizzo dei comandi, ho cercato di commentare il punti principali, se sono stato poco chiaro chiedo venia ma a quest'ora comincio a schizzare... xD
Per qualsiasi chiarimento domanda pure!
Ultima modifica effettuata da Dedalux il 27/04/2013 alle 2:30
this.musicList.Items.Add(new MusicItem());//Item di prova
}
Assegni correttamente al DataContext della ListView un'istanza di ViewMusic. (poi scoprirai che si sono dei metodi migliori)
Sbagli il passaggio successivo: non è dal "code behind" della View che aggiungi gli elementi.
Codice sorgente - presumibilmente C++
public ViewModelMusic viewModelMusic;
public MainWindow()
{
InitializeComponent();
this.viewModelMusic=new ViewModelMusic();
this.musicList.DataContext=this.viewModelMusic;
ModelMusic item =new ModelMusic();
item.file="File";
this.viewModelMusic.items.Add(item);
item.check=true;
}
publicclass ViewModelMusic : ViewModelBase
{
public ObservableCollection<ModelMusic> items { get; set;}
public ViewModelMusic()
{
items =new ObservableCollection<ModelMusic>();
}
}
publicclass ModelMusic
{
publicbool check { get; set;}
publicbool locked { get; set;}
public string file { get; set;}
public string title { get; set;}
publicint ID { get; set;}
}
Scusate ma non sono riuscito ada aprire VS in questi giorni, ennesimo grazie XD Ho riadattato come sopra concentrandomi solo sul inserimento degli items ma... nulla, dove sbaglio? Come inserisco gli items?
Mi sembra tutto corretto...
Il problema potrebbe essere nello XAML.
Hai controllato che la proprietà ItemsSource della ListView sia = {Binding Path=items}?
Perchè il DataContext è il ViewModel, ma lei non sa da che proprietà ottenere i dati.
Sennò se non è un problema prova a caricare il progetto che diamo un'occhiata.
P.S. quando nel post precedente ti ho scritto che non si dovrebbe agire dal code-behind della View sul ViewModel intendevo l'azione che stai facendo ora di aggiungere gli items nel costruttore della Window.
Il modo più corretto sarebbe, in questo caso, farlo nel costruttore del ViewModel, più o meno così
Codice sorgente - presumibilmente C# / VB.NET
public ViewModelMusic()
{
[b]items = new ObservableCollection<ModelMusic>();[/b]
// aggiungere da qua gli elementi
for (int i = 1; i <= 10; i++)
{
this.items.Add(new ModelMusic(i, true));
}
}
P.P.S. non è necessario mettere il prefisso Model, in genere si usa solo per i ViewModel
Ultima modifica effettuata da Dedalux il 04/05/2013 alle 23:49
Si si la modifica al nome delle classi l'ho fatta solo per comodità :-)
Si l'items è bindato, ho provato sia con {Binding items} che con {Binding Path=items}
ma viene generata un eccezione del XAML
Il problema è nel DataTemplate della colonna check, dove scrivi
Codice sorgente - presumibilmente Plain Text
Click={Binding changeCheck}
cerchi di bindare il click ad una proprietà "changeCheck" del DataContext. L'eccezione che ti da', che per completezza scrivo ed è una XamlParseException (Provide value on 'System.Windows.Data.Binding' threw an exception.), significa che non riesce a parsare lo XAML perchè si blocca nel momento in cui deve creare quel binding.
Ora, trovata la causa, c'è da dire che non è necessario gestire quell'evento click. Se vai a guardarti bene l'esempio che ti ho passato, quando selezioni un item, in basso puoi clickare sulla checkbox e cambiare il valore dell'item selezionato, e dando un'occhiata allo XAML, noterai che non ho gestito l'evento click, perchè come ti era già stato detto, fa tutto il databinding.
In poche parole povere, togli la riga incriminata e prova.
Che errore banalotto XD chiedo venia, era rimasto dai vecchi codici.
Ok ora il tutto funziona alla grande GRazie :-)
Ma sentite cosa intendete per bindare meglio il view model e per inserire gli item al di fuori dello stesso, che operazioni devo fare?
Il modo migliore per eseguire il binding del ViewModel alla View, è tramite la cosiddetta Dependency Injection.
E' una tecnica comunissima che consiste nel "iniettare" la dipendenza, ossia l'oggetto da cui una classe X dipende, dall'esterno, non è quindi essa a gestirne il ciclo di vita (creazione e distruzione), ma gli viene solo dato da usare.
Questa tecnica ha svariati vantaggi, principalmente slega dall'implementazione. Ossia potresti avere più dipendenze che fanno la stessa cosa in modi diversi, e potresti dover cambiare l'implementazione da usare. Normalmente dovresti modificare un sacco di codice. Con la dependency injection modifichi poche parole, e forse solo una.
Ci sono vari tecniche di dependency injection. La più comune è la Constructor Injection: initettare la dipendenza tramite costruttore. L'hai sempre usata anche te:
Codice sorgente - presumibilmente C# / VB.NET
var x = new X(dipendenza1, dipendenza2, ...);
Quindi avrai qualcosa del tipo
Codice sorgente - presumibilmente C# / VB.NET
public MyView(ViewModelBase viewModel)
{
this.InitializeComponent();
this.DataContext = viewModel;
}
In questo modo, puoi iniettare qualsiasi implementazione di ViewModelBase. Molto improbabile che tu voglia passargli un altro tipo di ViewModel, ma è per farti capire
E questo è tutto ciò che dovresti aver bisogno di scrivere nella View (a parte eventuale codice che gestisce la grafica).
Su internet ci sono un sacco di articoli sulla DI se ti interessa. Anche se a volte sono confusionari nello spiegare un concetto abbastanza semplice.
Per quanto riguarda l'esecuzione di azione, la View dirige il ViewModel tramite i "comandi" di cui ti avevo parlato, non sono altro che proprietà, quindi bindabili (in genere su button), ma che fanno qualcosa, perchè contengono un metodo.
Quindi potresti avere un comando Add, così come Delete, Edit, ecc..
Nell'esempietto che ti avevo caricato, il pulsante Add usa un command. Guarda lo XAML del button, e la proprietà del ViewModel.
Poi ci sarebbero 2 tipi di comandi: normali, e parametrizzati. Quello dell'esempio è normale (che avrei dovuto fare parametrizzato perchè sarebbe stato più adatto), e quello appunto col parametro ha la semplice caratteristica di avere un dato da manipolare quando compie la sua azione.
Se sono stato poco chiaro dimmelo.
EDIT: mi sono dimenticato di dire che quando si parla di dependency injection, chiaramente c'è bisogno di un terzo qualcosa che prende classe X e dipendenza e li mette insieme. Questo terzo si definisce "container" o "inversion of contorl container". E' il cuore di ogni framework per MVVM. Ce ne sono parecchi in giro.
Il più essenziale è quello che ti abbiamo suggerito, SimpleIoC di MVVM Light, sennò qua c'è una lista dei più famosi http://stackoverflow.com/questions/1280462/what-mvvm-frame ....
Ultima modifica effettuata da Dedalux il 06/05/2013 alle 14:34