7375


System.Windows.Controls.ContextMenuクラスをXAMLではなくC#のコードから生成しています。階層構造は以下のとおりで、カッコ内はバインドされたキーです。

このコンテキストメニューが開いた状態で、B→Aと押すとMenu2-1が実行されるようにしたいのですが、どのようにしたら良いのでしょうか。

[code]

    ContextMenu
      Menu1 (A)
      Menu2 (B)
        Menu2-1 (A)
        Menu2-2 (B)
      Menu3 (C)
    
[/code]


CC BY-SA 3.0
2015-03-03T03:50:56.847
7350
2015-03-03T08:55:26.680
2015-03-03T04:56:30.927
7722
7722
question
c# wpf
階層構造を持ったコンテキストメニューをキーボードで操作する


ご質問の意図として、

  1. コンテキストメニューにアクセスキーを指定したい
  2. コンテキストメニューにコマンドをバインドして実行したい

のどちらなのか、意図を取りかねましたので分けてご回答いたします。  
尚、前提として、

[code]

    <Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"/>
    
[/code]

のような極めて単純なWindowを定義済みとご理解ください。

## コンテキストメニューにアクセスキーを指定したい

に関しては、ContextMenuの中に含ませるMenuItemのHeaderプロパティの中に、以下のように、アンダースコアに続いて、目的のキーを指定することで可能です。

[code]

    var menuItem = new MenuItem {Header = "ファイル(_F)"};
    
[/code]

## コンテキストメニューにコマンドをバインドして実行したい

この場合、Xamlではなく、CSharpにて定義したいとのことなので、MainWindowのCtorのタイミングでコンテキストメニューを生成して、MainWindowのコンテキストメニューとして登録するなら、以下のようなコードになるかと思います。

[code]

    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    
    namespace WpfApplication2
    {
    /// <summary>
    ///     MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        private static readonly ICommand ShowMessageCommand = new RoutedCommand("ShowMessageCommand", typeof (MenuItem));
    
    
        public MainWindow()
        {
            InitializeComponent();
    
            CommandBinding bind = new CommandBinding(ShowMessageCommand, ShowCommand);
    
    
            ContextMenu contextMenu = new ContextMenu();
    
    
            MenuItem menuItem = new MenuItem {Header = "A(_A)", Command = ShowMessageCommand};
            menuItem.CommandBindings.Add(bind);
            contextMenu.Items.Add(menuItem);
    
            menuItem = new MenuItem {Header = "B(_B)"};
    
            MenuItem subItem = new MenuItem {Header = "A-A(_A)", Command = ShowMessageCommand};
            subItem.CommandBindings.Add(bind);
            menuItem.Items.Add(subItem);
    
            subItem = new MenuItem {Header = "B-B(_B)", Command = ShowMessageCommand};
            subItem.CommandBindings.Add(bind);
            menuItem.Items.Add(subItem);
    
            contextMenu.Items.Add(menuItem);
    
    
            menuItem = new MenuItem {Header = "C(_C)", Command = ShowMessageCommand};
            menuItem.CommandBindings.Add(bind);
            contextMenu.Items.Add(menuItem);
    
            ContextMenu = contextMenu;
        }
    
    
        private void ShowCommand(object sender, ExecutedRoutedEventArgs e)
        {
            MenuItem item = sender as MenuItem;
    
            if (item != null)
            {
                MessageBox.Show(this, "コンテキストメニューの\"" + item.Header + "\"に対応するコマンドが実行されました。");
            }
        }
    }
    
[/code]

}

上記サンプルでは、RoutedCommandを利用したCommandBindingを利用しておりますが、適宜そこは変更していただければと思います。  
また、蛇足ながら、コマンドではなく、特定のイベントに対応した処理をする場合は、MenuItemの当該イベントにイベントハンドラを登録すれば可能です。


CC BY-SA 3.0
2015-03-03T08:55:26.680
7375
2015-03-03T08:55:26.680
7287
7350
answer