2009-05-22 58 views
19

我有一个上下文菜单。它绑定到其他的收集和它有一个定义的ItemTemplate这样的:在DataTemplate中为MenuItem指定命令

<ContextMenu 
    ItemsSource={Binding ...} 
    ItemTemplate={StaticResource itemTemplate} 
    /> 

ItemTemplate中是一个简单的DataTemplate中有一个TextBlock:

<DataTemplate x:Key="itemTemplate"> 
    <TextBlock Text={Binding ...} /> 
</DataTemplate> 

如何绑定命令属性菜单项到底层对象的属性?

回答

24

我认为你需要用你的TextBlock在菜单项:

<DataTemplate x:Key="itemTemplate"> 
    <MenuItem Command={Binding ...}> 
     <TextBlock Text={Binding ...} /> 
    </MenuItem> 
</DataTemplate> 

但是我没有在我面前的IDE现在试试这个。让我知道事情的后续。


看起来你需要使用ItemContainerStyle所看到here。对不起,领导与你在一开始出现在错误的道路 - 但我在IDE的前拿到这个工程:

<ContextMenu.ItemContainerStyle> 
    <Style TargetType="MenuItem"> 
     <Setter Property="Command" Value="{Binding ...}"/> 
    </Style> 
</ContextMenu.ItemContainerStyle> 
+3

实际上,这将增加TextBlock中的菜单项的项目集合。并且它还将MenuItem放入另一个MenuItem中。 – arconaut 2009-05-22 17:04:26

+0

但与您的帖子,我开始思考MenuItem本身的模板,这可能是我需要的。 – arconaut 2009-05-22 17:06:13

+0

是的,这就是我一分钟前自己试过的。 – arconaut 2009-05-22 18:07:42

4

虽然这仅仅是马丁·哈里斯的回答略有变化,我想我会分享无论如何。我发现它更有益于整个集合指定单个命令,并沿CommandParameter派:

<MenuItem.ItemContainerStyle> 
    <Style TargetType="MenuItem"> 
     <Setter Property="Command" Value="{x:Static v:ViewModel.CommandForAll}"/> 
     <Setter Property="CommandParameter" Value="{Binding ValueForCommand}"/> 
    </Style> 
</MenuItem.ItemContainerStyle> 

然后你就可以决定如何在处理程序命令来完成:

private void CommandForAll_Executed(object sender, ExecutedRoutedEventArgs e) 
{ 
    var cmdParam = e.Paramater as ExpectedType 
    if (cmdParam != null) 
     //DoStuff... 
} 
-2

主窗口的.xaml

<Window.ContextMenu> 
     <ContextMenu x:Name="winCM"> 

      <!--<ContextMenu.ItemContainerStyle> 
       <Style TargetType="MenuItem"> 
        <Setter Property="Command" Value="{Binding CloseCommand}" /> 
       </Style> 
      </ContextMenu.ItemContainerStyle>--> 

      <MenuItem Name="menuItem_Close" Header="Close" Command="{Binding Path=DataContext.CloseCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/> 

      <!--Command="{Binding Path=PlacementTarget.DataContext.CloseCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"--> 
     </ContextMenu> 
    </Window.ContextMenu> 

MainWindow.cs

public partial class MainWindow : Window 
{ 
     private bool _canCloseCommandExecute; 

     public bool CanCloseCommand 

     { 
      get 
      { 
       return _canCloseCommandExecute; 
      } 
     } 
     private RelayCommand _closeCommand; 
     public ICommand CloseCommand 
     { 
      get 
      { 
       if (_closeCommand == null) 
       { 
        _closeCommand = new RelayCommand(p => this.OnClose(p), p => CanCloseCommand); 
       } 
       return _closeCommand; 
      } 
     } 

     public void OnClose(object obj) 
     { 
      Close(); 
     } 

     public MainWindow() 
     { 
      InitializeComponent(); 

      /* This will do the trick here */ 
      this.winCM.DataContext = this; 
      this._canCloseCommandExecute = true; 
     } 
} 

RelayCommand.cs

public class RelayCommand : ICommand 
    { 
     #region Fields 

     readonly Action<object> _execute; 
     readonly Predicate<object> _canExecute; 

     #endregion // Fields 

     #region Constructors 

     public RelayCommand(Action<object> execute) 
      : this(execute, null) 
     { 
     } 

     public RelayCommand(Action<object> execute, Predicate<object> canExecute) 
     { 
      if (execute == null) 
       throw new ArgumentNullException("execute"); 

      _execute = execute; 
      _canExecute = canExecute; 
     } 
     #endregion // Constructors 

     #region ICommand Members 

     [DebuggerStepThrough] 
     public bool CanExecute(object parameter) 
     { 
      return _canExecute == null ? true : _canExecute(parameter); 
     } 

     public event EventHandler CanExecuteChanged 
     { 
      add 
      { 
       CommandManager.RequerySuggested += value; 
      } 
      remove 
      { 
       CommandManager.RequerySuggested -= value; 
      } 
     } 

     public void Execute(object parameter) 
     { 
      _execute(parameter); 
     } 

     #endregion // ICommand Members 
    }