2011-01-25 4 views
13

Nel mio file XAML ho un DataGrid con un menu di scelta rapida. L'origine dati è un ViewModel che ha una proprietà EntityCollection (una ObservableCollection) come ItemsSource di DataGrid e un'altra raccolta ContextMenu.MenuItems che funge da origine dati per creare un menu di scelta rapida su DataGrid. Gli elementi di questa collezione hanno una proprietà Command che mi legano alla proprietà Comando delle voci di menu:Associazione di un parametro di comando del menu di scelta rapida a una proprietà datagrid

<DataGrid Name="EntityDataGrid" ItemsSource="{Binding EntityCollection}" Height="450"> 
    <DataGrid.ContextMenu> 
    <ContextMenu ItemsSource="{Binding Path=ContextMenu.MenuItems}"> 
     <ContextMenu.ItemContainerStyle> 
     <Style TargetType="{x:Type MenuItem}"> 
      <Setter Property="Command" Value="{Binding Command}" /> 
      <Setter Property="CommandParameter" 
        Value="{Binding ElementName=EntityDataGrid, Path=SelectedItems}" /> 
     </Style> 
     </ContextMenu.ItemContainerStyle> 
    </ContextMenu> 
    </DataGrid.ContextMenu> 
</DataGrid> 

L'azione per il comando di voce di menu ha la seguente firma nel ViewModel:

private void SelectedItemsAction(object parameter) 
{ 
    // Do something with "parameter" 
} 

Ora il mio problema è che raggiungo lo SelectedItemsAction quando clicco su una voce del menu contestuale, ma lo parameter è null. Credo che il mio problema sia nel setter per la proprietà CommandParameter. Come potete vedere, voglio legare questa struttura al SelectedItems proprietà del DataGrid impostando il valore a: i valori più semplici

<Setter Property="CommandParameter" 
     Value="{Binding ElementName=EntityDataGrid, Path=SelectedItems}" /> 

che ho provato come un test:

<Setter Property="CommandParameter" 
     Value="{Binding ElementName=EntityDataGrid, Path=Height}" /> 

Qui parameter è ancora null. E poi solo per verificare se qualsiasi parametro raggiunge il mio metodo di azione a tutti:

<Setter Property="CommandParameter" 
     Value="10" /> 

Questo funziona, il parameter nel mio metodo di azione è ora davvero 10.

Cosa faccio di sbagliato per associare il valore CommandParameter a una proprietà di EntityDataGrid? È possibile a tutti?

Grazie per l'aiuto in anticipo!

risposta

7

Hai provato a eseguire un'associazione di Ancestor? Qualcosa di simile:

<Setter Property="CommandParameter" 
     Value="{Binding Path=SelectedItems, 
     RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" /> 
+0

Grande, grazie, questo funziona! (Ora ho solo bisogno di leggere un po 'di più sul binding WPF per capire cosa sta facendo esattamente il codice;)) – Slauma

+0

Sta salendo l'albero per trovare un oggetto che corrisponde a quel tipo. Il primo a venirne a contatto lo usa come contesto vincolante. – CodeWarrior

+0

Nel frattempo ho letto di più sul binding e ora è chiaro il motivo per cui il mio markup originale non ha funzionato e perché il tuo codice è il modo corretto. Grazie per la spiegazione! – Slauma

11

Il ContextMenu non è nella stessa parte del Visual albero è per questo che non è possibile utilizzare ElementName ecc per fare riferimento al DataGrid. Dovrai utilizzare lo PlacementTarget del ContextMenu. Provalo in questo modo

<ContextMenu ItemsSource="{Binding Path=ContextMenu.MenuItems}"> 
    <ContextMenu.ItemContainerStyle> 
     <Style TargetType="{x:Type MenuItem}"> 
      <Setter Property="Command" Value="{Binding Command}" /> 
      <Setter Property="CommandParameter" 
        Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, 
            Path=PlacementTarget.SelectedItems}" /> 
     </Style> 
    </ContextMenu.ItemContainerStyle> 
</ContextMenu> 
+0

Grazie, anche questo funziona! (Ho contrassegnato la soluzione di OffApps Cory come risposta accettata, solo perché ha risposto poche ore prima. Comunque grazie per il tuo impegno!) – Slauma

+2

+1 Finalmente trovato! Questo ha funzionato per me quando si utilizzava 'RelayCommand' insieme a 'CommandParameter' da MVVM Light Toolkit. Vorrei che WPF facesse funzionare 'ElementName' indipendentemente da dove fossero gli elementi nell'albero degli elementi. Grazie per aver condiviso questa variazione vincolante di 'ContextMenu'! – SliverNinja