我现在仍在摸索WPF,并且无法弄清楚为什么禁用此上下文菜单项:
<Window x:Class="DisabledMenuItemProblem.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DisabledMenuItemProblem"
Title="Window1" Height="300" Width="300">
<TextBlock Text="fooooobaaaaaar">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="Foo" Command="{x:Static local:MyCommands.FooBar}" />
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</Window>
using System.Windows;
using System.Windows.Input;
namespace DisabledMenuItemProblem
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
CommandBindings.Add(new CommandBinding(MyCommands.FooBar, FooExecuted, CanFooExecute));
}
public void FooExecuted(object sender, ExecutedRoutedEventArgs e)
{ MessageBox.Show("Foo!"); }
public void CanFooExecute(object sender, CanExecuteRoutedEventArgs e)
{ e.CanExecute = true; }
}
public static class MyCommands
{
public static RoutedCommand FooBar = new RoutedCommand();
}
}
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
令我感到困惑的是,如果我在窗口中抛出一个按钮并将其命令设置为FooBar,它就会起作用,一旦执行它,就会启用上下文菜单!
干杯,克里斯.
Mua*_*Dib 10
这是我使用的一般模式....
首先,将您的命令保存在自己的静态类中,这样可以促进重用等等....
public static class MyCommands
{
public static RoutedUICommand CmdFoo = new RoutedUICommand("CmdFoo",
"CmdFoo",
typeof(MyCommands));
}
Run Code Online (Sandbox Code Playgroud)
第二,在control/window/etc中注册命令.你想在它中使用它,通常在构造函数中
public MyControl
{
public MyControl()
{
CommandBindings.Add(
new CommandBinding( MyCommands.CmdFoo, // this is the command object
XCutFooCommand, // execute
CanXCuteFooCommand));// can execute?
}
Run Code Online (Sandbox Code Playgroud)
第三,在控件/窗口/等中创建处理程序.....
public void CanExecuteRerollCommand(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true; // can this command be executed?
e.Handled = true; // has this event been handled?
}
public void ExecuteRerollCommand(object sender, ExecutedRoutedEventArgs e)
{
// do stuff
}
}
Run Code Online (Sandbox Code Playgroud)
最后,你的xaml应该是这样的:
<ContextMenu>
<ContextMenu.CommandBindings>
<CommandBinding Command="foo:MyCommands.CmdFoo"
CanExecute="CanExecuteRerollCommand"
Executed="ExecuteRerollCommand" />
</ContextMenu.CommandBindings>
<MenuItem Header="Reroll" Command="foo:MyCommands.CmdFoo"/>
</ContextMenu>
Run Code Online (Sandbox Code Playgroud)
注意没有约束力.此外,注意<CommandBinding>
的<ContextMenu>
.这是一个参考....
http://www.wiredprairie.us/journal/2007/04/commandtarget_menuitem_context.html
正在禁用的命令在此站点上处理
小智 8
对于任何寻找这个问题答案的人 - 在浏览互联网之后,我发现最有效的答案是在菜单项的任何声明中包含以下内容,需要其命令被其"所有者"听到.
用外行人的话说; 如果你想通过你正确点击的东西听到你的上下文菜单的命令.添加此代码:
CommandTarget ="{Binding Path = PlacementTarget,RelativeSource = {RelativeSource AncestorType = ContextMenu}}"
例:
<ContextMenu>
<MenuItem Header="Close" Command="Application.Close" CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
</ContextMenu>
Run Code Online (Sandbox Code Playgroud)
这也适用于模板(我发现很多其他解决方案不支持).以下是对其他地方声明的含义的解释(我在解释事情时骇人听闻):
每个FrameworkElement都有一个DataContext,它是一个任意对象.数据绑定的默认源是DataContext.您可以使用RelativeSource.Self来更改绑定到FrameworkElement本身而不是其DataContext的源.因此,RelativeSource部分只是将您从FrameworkElement的DataContext"上升一级"移动到FrameworkElement本身.进入FrameworkElement后,您可以指定其任何属性的路径.如果FrameworkElement是Popup,它将具有PlacementTarget属性,该属性是Popup相对于其定位的另一个FrameworkElement.
简而言之,如果你有一个相对于TextBox放置的Popup,那么该表达式将Popup的DataContext设置为TextBox,结果Popped正文中的某个地方{Binding Text}将绑定到TextBox的文本.
老实说,我希望这些信息可以帮助那些刚接触WPF的人,这个周末我经历过的头痛......虽然它确实教会了我很多!
史蒂夫