我有一个包含菜单和子菜单的应用程序。 我已经对一些子菜单项目附加了应用程序命令,例如剪切、复制和粘贴。
还有一些其他没有应用程序命令的菜单项。
我如何将自定义命令绑定到这些子菜单项?
我已经阅读了这篇文章,但无法将事件附加到我的子菜单项。
我使用一个静态类,放在Window1类(或者无论窗口类名是什么)之后,在该静态类中创建RoutedUICommand类的实例:
public static class Command {
public static readonly RoutedUICommand DoSomething = new RoutedUICommand("Do something", "DoSomething", typeof(Window1));
public static readonly RoutedUICommand SomeOtherAction = new RoutedUICommand("Some other action", "SomeOtherAction", typeof(Window1));
public static readonly RoutedUICommand MoreDeeds = new RoutedUICommand("More deeds", "MoreDeeeds", typeof(Window1));
}
在窗口标记中添加一个命名空间,使用Window1类所在的命名空间:
xmlns:w="clr-namespace:NameSpaceOfTheApplication"
现在我可以像为应用程序命令一样为命令创建绑定:
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Open" Executed="CommandBinding_Open" />
<CommandBinding Command="ApplicationCommands.Paste" Executed="CommandBinding_Paste" />
<CommandBinding Command="w:Command.DoSomething" Executed="CommandBinding_DoSomething" />
<CommandBinding Command="w:Command.SomeOtherAction" Executed="CommandBinding_SomeOtherAction" />
<CommandBinding Command="w:Command.MoreDeeds" Executed="CommandBinding_MoreDeeds" />
</Window.CommandBindings>
例如,在菜单中使用绑定:
<MenuItem Name="Menu_DoSomething" Header="Do Something" Command="w:Command.DoSomething" />
Command.DoSomething
)必须是public,否则你会收到以下异常信息:“CommandConverter无法从System.String进行转换”。我猜测这是因为管理命令的代码可能在不同的程序集中,因此无法看到internal
属性。我上周刚开始学习WPF :D - Pressacco您可以直接在XAML中声明命令,而不是在静态类中定义它们。以下是一个示例(改编自Guffas的好例子):
<Window.Resources>
<RoutedUICommand x:Key="DoSomethingCommand" Text="Do Something" />
<RoutedUICommand x:Key="DoSomethingElseCommand" Text="Do Something Else" />
</Window.Resources>
<Window.CommandBindings>
<CommandBinding Command="{StaticResource DoSomethingCommand}" Executed="CommandBinding_DoSomething" />
<CommandBinding Command="{StaticResource DoSomethingElseCommand}" Executed="CommandBinding_DoSomethingElse" />
</Window.CommandBindings>
...
<MenuItem Name="Menu_DoSomething" Header="Do Something" Command="{StaticResource DoSomethingCommand}" />
CommandBinding_DoSomething
和CommandBinding_DoSomethingElse
是C#代码。3./4. 关于RoutedCommands与常规Button_Click绑定的优势的一般讨论,请参见例如http://joshsmithonwpf.wordpress.com/2008/03/18/understanding-routed-commands/(第“谁关心?”部分)。 - Heinzi我知道我的答案来晚了,但我希望它能对未来有所帮助。
我喜欢Guffa和Heinzi的回答,但是你只需要使用一个命令就可以达到之前的结果。我通常使用Help命令。
<Window.CommandBindings>
<CommandBinding Command="{StaticResource Help}" Executed="HelpExecuted" />
</Window.CommandBindings>
我每次调用都使用CommandParameter参数,例如:
<Window.InputBindings>
<KeyBinding Command="{StaticResource Help}" Key="A" Modifiers="Ctrl" CommandParameter="Case1"/>
<KeyBinding Command="{StaticResource Help}" Key="B" Modifiers="Ctrl" CommandParameter="Case2"/>
<KeyBinding Command="{StaticResource Help}" Key="C" Modifiers="Ctrl" CommandParameter="Case3"/>
<KeyBinding Command="{StaticResource Help}" Key="D" Modifiers="Ctrl" CommandParameter="Case4"/>
<MouseBinding Command="{StaticResource Help}" MouseAction="LeftDoubleClick" CommandParameter="Case5" />
</Window.InputBindings>
或者<Button Command="Help" CommandParameter="Case6" Content="Button">
<Button.InputBindings>
<KeyBinding Command="{StaticResource Help}" Gesture="Ctrl+D" CommandParameter="Case7"/>
</Button.InputBindings>
</Button>
并且在cs文件中
private void HelpExecuted(object sender, ExecutedRoutedEventArgs e)
{
string str = e.Parameter as string;
switch (str)
{
case null://F1 Pressed default Help
//Code
break;
case "Case1":
//Code
break;
case "Case2":
//Code
break;
case "Case3":
//Code
break;
case "Case4":
break;
case "Case5":
//Code
break;
case "Case6":
//Code
break;
case "Case7":
//Code
break;
}
e.Handled = true;
}
如果你正在使用 MVVM 模式
private void HelpExecuted(object sender, ExecutedRoutedEventArgs e)
{
string str = e.Parameter as string;
Mvvm_Variable.Action(Input: str);
e.Handled = true;
}
并将开关移动到ViewModule站点。Action是同一ViewModule类中的一个方法。
RoutedUICommand
。这个类有一个Text
属性,从中取出文本以自动填充调用该命令的菜单条目(并且可以在其他地方使用——我经常通过共享模板将按钮文本绑定到它上面)。如果您使用一个命令(比如“帮助”),所有菜单项都将具有在Help.Text
中定义的相同的单个文本片段。根据您喜欢的架构,这可能不是一个大问题,但我认为这是需要注意的事情。 - Bob Sammers