如何将上下文菜单的单击处理程序绑定到函数
本文关键字:程序 处理 绑定 函数 单击 上下文 菜单 | 更新日期: 2023-09-27 17:56:25
我有一些像下面这样的 XAML:
<UserControl x:Class="Foo">
<UserControl.Resources>
<ContextMenu x:Key="ContextMenu1">
<MenuItem Header="Command 1a"/>
<MenuItem Header="Command 1b"/>
</ContextMenu>
<ContextMenu x:Key="ContextMenu2">
<MenuItem Header="Command 2a"/>
<MenuItem Header="Command 2b"/>
</ContextMenu>
</UserControl.Resources>
<DockPanel>
<TreeView>
<TreeView.Resources>
<DataTemplate DataType="{x:Type Type1}">
<StackPanel ContextMenu="{StaticResource ContextMenu1"}/>
</DataTemplate>
<DataTemplate DataType="{x:Type Type2}">
<StackPanel ContextMenu="{StaticResource ContextMenu2"}/>
</DataTemplate>
</TreeView.Resources>
</TreeView>
</DockPanel>
</UserControl>
以及类似于以下内容的代码:
public class Type1 {
public void OnCommand1a() {}
public void OnCommand1b() {}
}
public class Type2 {
public void OnCommand2a() {}
public void OnCommand2b() {}
}
我需要做什么才能单击菜单上的相应项目调用相应的函数?
如果我添加:
Command="{Binding Path=OnCommand1a}" CommandTarget="{Binding Path=PlacementTarget}"
等等,然后在运行时我收到有关 OnCommand1a 如何不是属性的错误。 一些搜索表明这与 RoutedUIEvent 有关,但我真的不明白这是关于什么的。
如果我使用
Click="OnCommand1a"
然后,它在用户控件上查找 OnCommand1a(),而不是在绑定到数据模板的类型上查找。
处理这个问题的标准方法是什么?
首先,
你需要一个扩展ICommand的类。您可以使用它:
public class DelegateCommand : ICommand
{
private readonly Action<object> executeMethod = null;
private readonly Func<object, bool> canExecuteMethod = null;
public event EventHandler CanExecuteChanged
{
add { return; }
remove { return; }
}
public DelegateCommand(Action<object> executeMethod, Func<object, bool> canExecuteMethod)
{
this.executeMethod = executeMethod;
this.canExecuteMethod = canExecuteMethod;
}
public bool CanExecute(object parameter)
{
if (canExecuteMethod == null) return true;
return this.canExecuteMethod(parameter);
}
public void Execute(object parameter)
{
if (executeMethod == null) return;
this.executeMethod(parameter);
}
}
然后,在你的类 Type1 中,你必须声明这一点:
public DelegateCommand OnCommand1a {get; private set;}
并通过以下方式在 Type1 构造函数中设置它:
OnCommand1a = new DelegateCommand(c => Cmd1a(), null);
其中 Cmd1a 是:
private void Cmd1a()
{
//your code here
}
最后,在你的 xaml 中:
Command="{Binding Path=OnCommand1a}"