2013-03-22 62 views
9

我想將一個contextmenu綁定到一個命令列表。MVVM中的ContextMenu

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

commandToStringConverter簡單命令的列表轉換爲字符串調用列表中的每個命令的ToString()的列表。

我該如何實現每個MenuItem中的Command被調用?

+0

*您probabbly *應該考慮使用其他尚未轉換器,轉換每一個{結合}實際命令調用。 – Tigran

+0

轉換器返回一個Func列表? –

回答

16

我會用一個小的「視圖模型」來保存這樣的命令的信息。

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

讓你的視圖模型中的集合,其應該得到的背景下操作,如

ObservableCollection<ContextAction> Actions {get;set;} 

,只是這個集合綁定到你的文本菜單。

<Grid.ContextMenu> 
    <ContextMenu ItemsSource="{Binding Actions}/> 

ItemTemplate中的文本菜單項目現在可以訪問名字,你可能需要的命令和其他任何。改變CommandParameter也可能是有用的,因爲它會調用具有動作擁有元素的命令,而不是動作本身。

+1

+1你更快:) – blindmeis

+0

任何人都有一個想法如何處理與分隔符和子菜單的ContextMenu?此解決方案似乎只對一組同類對象有用。 –

+0

子菜單一樣簡單。您只需將ContextMenu的ItemContainerStyle與ItemsSource的setter一起使用,並綁定到ContextAction中的ObservableCollection 類型的新屬性。對於分隔符,請參見[this](http://stackoverflow.com/questions/4823760/how-to-add-horizo​​ntal-separator-in-a-dynamically-created-contextmenu)解決方案。 – dowhilefor

11

我用這樣的:在你的ContextMenu的DataContext

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

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

在XAML中

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

書面沒有IDE,所以也許有些語法錯誤there

+3

該解決方案嵌套了MenuItem的控制 –

2

一種改進的下面@blindmils解決XAML版本:

<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>