3

MenuItemsに接続する のさまざまなコマンドをバインドしようとしContextMenuていButtonます。staticしかし、このために、すべてのコマンドを、自分の にインポートしたクラスのように定義していますResourceDictionary

public class DesignerCanvas{
    ....
    public static RoutedCommand MyCommand = new RoutedCommand();
    ....
}

私のMainWindow.xamlでは、次のように実装を使用してこのコマンドをフックしてMainWindow.xaml.csいます。

<CommandBinding Command="{x:Static Designer:DesignerCanvas.MyCommand}"
                    Executed="DoStuff"
                    CanExecute="CanDoStuff" /> 

そして、私のResourceDictionary.xamlでは、を使用して をButtonフックしています:ContextMenuTriggers

    <Button x:Name="btnMyButton" Content="Click this">
      <Button.Style>
        <Style TargetType="{x:Type Button}">
          <Style.Triggers>
            <EventTrigger RoutedEvent="Click">
              <EventTrigger.Actions>
                <BeginStoryboard>
                  <Storyboard>
                    <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="ContextMenu.IsOpen">
                      <DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True"/>
                    </BooleanAnimationUsingKeyFrames>
                  </Storyboard>
                </BeginStoryboard>
              </EventTrigger.Actions>
            </EventTrigger>
          </Style.Triggers>
          <Setter Property="ContextMenu">
            <Setter.Value>
              <ContextMenu>
                <MenuItem x:Name="myMenu" Header="MyMenuItem 1">
                  <MenuItem x:Name="menuItem1" Header="MySubMenuItem 1"
Command="{x:Static DesignerItems:DesignerCanvas.MyCommand}">     <<<=== Command Binding
                    <MenuItem.Icon>
                      <Image Source="myImage.png" Width="20"/>
                    </MenuItem.Icon>
                  </MenuItem>
                </MenuItem>
              </ContextMenu>
            </Setter.Value>
          </Setter>
        </Style>
      </Button.Style>
    </Button>

Commandしかし、XAML で指定されたメニュー項目が として表示されており、とdisabledのどちらもデバッガーにヒットしていないため、これは機能していないようです。また、私はこれにViewModelを使用していないため、次のようなものを書くことができません:CanDoStuff()DoStuff()

<MenuItem Command="{Binding Path=somePathInViewModel, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" />

どうすればこれを行うことができますか、どんな助けでも大歓迎です。前もって感謝します。

4

2 に答える 2

3

最後にそれが機能するようになりましたが、いくつかのばかげた間違いをしていました!

staticコマンドの初期化をContextMenuその所有者として持つように変更する必要がありました

public static RoutedCommand MyCommand = new RoutedCommand("MyCommand", typeof(ContextMenu));

MainWindow.xaml.cs、コマンド バインディングを登録するメソッドを追加し、MainWindowのコンストラクターから呼び出します。

private void InitializeMenuItemsCommands()
    {
        CommandManager.RegisterClassCommandBinding(typeof(ContextMenu), new CommandBinding(DesignerCanvas.TestDialog, OpenTestDialog, CanOpenTestDialog));
    }

そして最後に、イベントのCanExecuteハンドラーExecuted:

private void CanOpenTestDialog(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = true; // set if MenuItem is enabled
}

private void OpenTestDialog(object sender, ExecutedRoutedEventArgs e)
{
    // handle the MenuItem click here
}

ResourceDictionaryの forMenuItemで何も変更する必要はありませんでしたので、ここに再び MenuItem があります:

<MenuItem x:Name="menuItem1" Header="MySubMenuItem 1"
Command="{x:Static DesignerItems:DesignerCanvas.MyCommand}">     <<<=== Command Binding
                <MenuItem.Icon>
                  <Image Source="myImage.png" Width="20"/>
                </MenuItem.Icon>
              </MenuItem>
于 2013-11-12T07:42:45.853 に答える
3

コードで実際にすべてうまくやっていますが、WPF の ContextMenus に関する隠れたバグや機能はほとんどありません。それらの悪者は、WPF の通常の機能を欠いています。ContextMenu は実際には WPF の各コントロールで使用できる単なるダンプ プロパティであり、ユーザーが右クリックすると項目のリストが VisualTree に挿入されます。

この問題を解決するには、Style で ContextMenu を設定せず、Window レベルで CommandBinding を設定せず、代わりに ContextMenu のレベルで設定します。

最も重要なのは、ContextMenu を Style に設定しないことです!

編集:

ContextMenu を Style から離して配置し、CommandBinding を次のように設定します。

<ContextMenu>
    <ContextMenu.CommandBindings>
        <CommandBinding Command="foo:MyCommands.CmdFoo" 
                        CanExecute="CanExecuteRerollCommand" 
                        Executed="ExecuteRerollCommand" />
    </ContextMenu.CommandBindings>
    <MenuItem Header="Reroll"  Command="foo:MyCommands.CmdFoo"/>
</ContextMenu>
于 2013-11-09T19:06:54.297 に答える