【问题标题】:How to bind a ContextMenu's click handler to a function如何将 ContextMenu 的点击处理程序绑定到函数
【发布时间】:2014-04-03 07:04:43
【问题描述】:

我有一些 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" 

然后它在 UserControl 上而不是在绑定到 DataTemplate 的类型上查找 OnCommand1a()。

处理这个问题的标准方法是什么?

【问题讨论】:

标签: c# wpf wpf-controls


【解决方案1】:

首先,您需要一个扩展 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}"    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多