Utilizzo del DataContext del genitore (WPF – Binding del comando del menu dinamico)

Ho controllato questo web e google e le soluzioni non hanno funzionato per me.

Ho un comando sul ViewModel di un UserControl. Bene, l’usercontrol ha un ItemsControl associato a ObservableCollection. All’interno del DataTemplate di ItemsControl.ItemTemplate ho un pulsante e voglio usare il comando. Non riesco a bind il comando perché all’interno di DataTemplate, il datacontext non è il ViewModel ma un object di ObservableCollection.

La domanda è: come posso associare il pulsante al comando in caso di perdita del datacontext padre?

Penso che questo abbia bisogno di una soluzione facile perché penso che questo sia un problema comune.

Immagina questo scenario:

Hai un object ListBox con una ObservableCollection come ItemsSource, quindi stai usando un datatemplate all’interno del ListBox per ogni elemento della collezione. Bene, si desidera eliminare l’elemento selezionato e si inserisce un pulsante in ogni riga per quel lavoro. Come si fa a farlo?

In MVP, posso farlo nell’evento click del pulsante:

Button but = e.Source as Button; if (but != null) Presenter.ActualNote = but.DataContext as Note; 

In breve. Si invia il datacontext della riga (l’elemento selezionato) al presentatore.

Ma come posso farlo nel modo mvvm? Perché ho bisogno di usare un comando ma non posso assegnare il comando al pulsante perché il pulsante non sa nulla di ViewModel (dove esiste il comando).

Come puoi vedere, il pulsante deve esistere all’interno del datatemplate, quindi il datacontext non è più il ViewModel …. Ecco perché ho bisogno di accedere al DataContext del genitore, per accedere al comando.

Spero che tu capisca meglio il mio problema.

Grazie.

    Se si desidera una soluzione sporca, MVVM-breaking, quindi impostare il tag = “{Binding}” sul pulsante e gestire l’evento Click. Nel gestore di eventi, chiama il comando sul ViewModel.

    Utilizza l’associazione sottostante per il comando del tuo pulsante:

     {Binding DataContext.CommandName, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MyUserControl}}} 

    Questo lo dirà per trovare il tuo UserControl e usare il suo DataContext.

    RelativeSource funziona, ma non penso sia giusto lasciare che i controlli si aggirino tra le proprietà degli altri. È strano che il pulsante posizionato all’interno di una vista object faccia qualcosa con un’origine dati esterna piuttosto che con l’object associato. Potrebbe essere necessario rivedere il design del codice del programma.

    Ok, allora che ne dici di modificare la tua class di dati in modo che abbia una proprietà che fa riferimento all’intera vista del modello?

    Se il tuo ItemsSource è di tipo ObservableCollection quindi modificare il tipo DataItem in questo modo:

     public class DataItem { public BusinessObject Value { get; set; } private ModelView modelView; public ModelView ModelView { get { return modelView; } } public DataItem(ModelView modelView) { this.modelView = modelView; } }