2011-01-25 11 views
13

W moim pliku XAML mam DataGrid z menu kontekstowym. Źródłem danych jest ViewModel, który ma właściwość EntityCollection (ObservableCollection) jako ItemsSource of DataGrid i inną kolekcję ContextMenu.MenuItems, która służy jako źródło danych do utworzenia menu kontekstowego w DataGrid. Elementy tej kolekcji mają Command nieruchomości, które wiążę z właściwością dowodzenie elementów menu:Powiązanie parametru polecenia menu kontekstowego z właściwością 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> 

Akcja dla polecenia menu zawiera następujące podpis w ViewModel:

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

Teraz mój problem polega na tym, że po kliknięciu elementu menu kontekstowego osiągam SelectedItemsAction, ale parameter to null. Uważam, że mój problem dotyczy ustawiacza dla właściwości CommandParameter. Jak widać, chcę związać nieruchomość na własność DataGrid SelectedItems ustawiając wartość:

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

próbowałem prostszych wartości jako test:

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

Tu parameter nadal jest null. A potem po prostu sprawdzić, czy każdy parametr osiąga moją metodę działania w ogóle:

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

To działa, parameter w moim metody działania jest teraz rzeczywiście 10.

Co robię źle przypisując wartość CommandParameter do właściwości EntityDataGrid? Czy to w ogóle możliwe?

Dziękujemy za pomoc z góry!

Odpowiedz

7

Czy próbowałeś wykonać powiązanie Ancestor? Coś jak:

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

Świetnie, dziękuję, to działa! (Teraz muszę tylko przeczytać nieco więcej o wiązaniu WPF, aby zrozumieć, co dokładnie robi twój kod;)) – Slauma

+0

Podchodzi do drzewa, aby znaleźć element, który pasuje do tego typu. Pierwszy, który do niego dojdzie, wykorzystuje go jako kontekst wiążący. – CodeWarrior

+0

W międzyczasie przeczytałem więcej o wiązaniu i teraz jest jasne, dlaczego mój oryginalny znacznik nie działa i dlaczego twój kod jest poprawny. Dzięki za wyjaśnienie! – Slauma

11

ContextMenu nie jest w tej samej części Visual Drzewo więc dlatego nie można używać ElementName itp odwoływać się do DataGrid. Będziesz musiał zamiast tego użyć PlacementTarget z ContextMenu. Wypróbuj tak, jak to

<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

Dziękuję, to też działa! (Zatwierdziłem rozwiązanie OffApps Cory jako zaakceptowaną odpowiedź, tylko dlatego, że odpowiedział kilka godzin wcześniej. W każdym razie dzięki za wysiłek!) – Slauma

+2

+1 Wreszcie znalazłem! To działało dla mnie przy użyciu 'RelayCommand' wraz z' CommandParameter' z MVVM Light Toolkit. Szkoda, że ​​WPF nie uczyniłoby elementu 'ElementName' bez względu na to, gdzie były elementy w drzewie elementów. Dziękuję za podzielenie się tą opcją "ContextMenu"! – SliverNinja

Powiązane problemy