如何从其 CanExecute 处理程序中获取 MenuItem?

How to get a MenuItem from within its CanExecute handler?

我怎样才能访问相关的MenuItem?它是即时创建的,所以我不能仅通过 xaml 文件中的名称来使用它。

private void menuItem_canExecute(object sender, CanExecuteRoutedEventArgs e)
{
    var snd = sender; // This is the main window
    var orgSource = e.OriginalSource; // This is a RichTextBox;
    var src = e.Source; // This is a UserControl

    // I think I must use the Command, but how?
    RoutedCommand routedCommand = e.Command as RoutedCommand;
}

CanExecuteRoutedEventArgs 有一个 OriginalSource 属性.

MSDN Doc for CanExecuteRoutedEventArgs

OriginalSender 可能是 TextBlock,也就是 "inside" MenuItem。您可能需要遍历可视化树才能找到类型为 MenuItem

parent

示例代码来自 here

public static T GetVisualParent<T>(this DependencyObject child) where T : Visual
{
    //TODO wrap this in a loop to keep climbing the tree till the correct type is found 
    //or till we reach the end and haven't found the type
    Visual parentObject = VisualTreeHelper.GetParent(child) as Visual;
    if (parentObject == null) return null;
    return parentObject is T ? parentObject as T : GetVisualParent<T>(parentObject);
}

像这样使用

var menuItem = e.OriginalSource.GetVisualParent<MenuItem>();
if (menuItem != null)
    //Do something....

您始终可以通过将命令 UI 元素绑定到它的 CommandParameter 属性 来将命令 UI 元素传递给命令,例如

<MenuItem ... CommandParameter="{Binding RelativeSource={RelativeSource Self}}"/>

现在您可以通过 CanExecuteRoutedEventArgs 的 Parameter 属性 访问 MenuItem:

private void menuItem_canExecute(object sender, CanExecuteRoutedEventArgs e)
{
    var menuItem = e.Parameter as MenuItem;
    ...
}