2013-03-22 17 views
9

Chcę powiązać menu kontekstowe z listą poleceń.Menu kontekstowe w MVVM

<Grid.ContextMenu> 
    <ContextMenu ItemsSource="{Binding ItemContextCommands, Converter={StaticResource commandToStringConverter}}"> 
      <ContextMenu.ItemTemplate > 
        <DataTemplate DataType="MenuItem"> 
          <MenuItem Command="{Binding}"></MenuItem> 
         </DataTemplate> 
       </ContextMenu.ItemTemplate> 
     </ContextMenu> 
</Grid.ContextMenu> 

The commandToStringConverter prostu zamienia listę poleceń do listy ciągów dzwoniących na ToString() na każde polecenie na liście.

W jaki sposób można uzyskać ustawienie Command w każdym MenuItem?

+0

You * probabbly * należy myśleć o użyciu innego jeszcze konwerter, który konwertuje każdy {Binding} do rzeczywistej rozmowy poleceń. – Tigran

+0

konwerter zwraca listę Func? –

Odpowiedz

16

Chciałbym użyć małego "modelu widoku" do przechowywania informacji dla takiego polecenia.

class ContextAction : INotifyPropertyChanged 
{ 
    public string Name; 
    public ICommand Action; 
    public Brush Icon; 
} 

zrobić kolekcję wewnątrz widoku modelu, który powinien otrzymać akcje kontekstowe jak

ObservableCollection<ContextAction> Actions {get;set;} 

i po prostu powiązać tę kolekcję do ContextMenu.

Element ItemTemplate dla elementów menu kontekstowego może teraz uzyskać dostęp do nazwy, polecenia i czegokolwiek, co może być potrzebne. Przydatna może być zmiana CommandParameter tak, aby wywoływał polecenie z elementami będącymi własnością, a nie samym działaniem.

+1

+1 byłeś szybszy :) – blindmeis

+0

Ktoś ma pomysł jak radzić sobie z ContextMenu z separatorami i podmenu? To rozwiązanie wydaje się być użyteczne tylko dla jednorodnego zbioru obiektów. –

+0

Podmenu są równie proste. Właśnie nadajesz ContextMenu ItemContainerStyle z ustawiaczem dla ItemsSource i powiążesz nową właściwość typu ObservableCollection wewnątrz ContextAction. Dla Separatorów zobacz rozwiązanie [this] (http://stackoverflow.com/questions/4823760/how-to-add-horizontal-separator-in-a-dynamically-created-contextmenu). – dowhilefor

11

używać coś takiego:

public class ContextMenuVM 
{ 
    public string Displayname {get;set;} 
    public ICommand MyContextMenuCommand {get;set;} 
} 

w swoim contextmenu datacontext:

public ObservableCollection<ContextMenuVM> MyCommandList {get;set;} 

w XAML

<ContextMenu ItemsSource="{Binding MyCommandList}"> 
     <ContextMenu.ItemTemplate > 
       <DataTemplate DataType="MenuItem"> 
         <MenuItem Header="{Binding Displayname}" Command="{Binding MyContextMenuCommand}"></MenuItem> 
        </DataTemplate> 
      </ContextMenu.ItemTemplate> 
    </ContextMenu> 

jej pisane bez IDE, więc może jakieś błędy składniowe w tam

+3

To rozwiązanie ma zagnieżdżoną kontrolę MenuItem –

2

Ulepszony XAML wersję @blindmils roztworu poniżej:

<ContextMenu ItemsSource="{Binding MyCommandList}"> 
    <ContextMenu.ItemContainerStyle> 
     <Style TargetType="MenuItem"> 
      <Setter Property="Header" Value="{Binding Displayname}" /> 
      <Setter Property="Command" Value="{Binding MyContextMenuCommand }" /> 
     </Style> 
    </ContextMenu.ItemContainerStyle> 
</ContextMenu> 
Powiązane problemy