1

我有一个 WPF MenuItem,它是从没有其他信息的函数返回的,我想将另一个(新)MenuItem 的单击事件设置为与第一个 MenuItem 相同的函数。

我已经在 Windows 窗体中看到了执行此操作的代码(例如,是否可以从一个控件“窃取”事件处理程序并将其提供给另一个控件?),但我找不到 WPF 路由事件的解决方案。

4

1 回答 1

0

当我需要在 WPF 中复制菜单项时,我按照建议使用命令模式,但是通过一些巧妙的技巧,您仍然可以支持事件处理程序(见下文)。我用来复制项目的代码看起来像这样,其中“项目”是我正在复制的旧 MenuItem:

MenuItem copy = new MenuItem();
copy.Header = item.Header;
copy.Icon = item.Icon;
copy.Command = item.Command;
copy.CommandParameter = item.CommandParameter;
foreach( CommandBinding binding in item.CommandBindings ) {
    copy.CommandBindings.Add( binding );
}
newCollection.Add( copy );

显然,您可能需要根据您倾向于使用的 MenuItem 的哪些功能来调整您复制的属性。我几乎坚持使用 Header、Icon 和 Command,所以这就是我实现的全部。

现在,如果您需要支持事件处理程序样式,您将需要某种构造抽象,因为您只能在分配给事件之前“玩”它。一旦您将事件处理程序添加到菜单项,它就无法检索了。如果你有一个实际的 RoutedEventHandler 对象(预订阅),你可以做这个小工作(其中“处理程序”是我包装的 RoutedEventHandler 实例):

ExecutedRoutedEventHandler executed = (sender, args) =>
{
    RoutedEventArgs innerArgs = new RoutedEventArgs();
    // The consumer probably shouldn't rely on these, but we'll copy them for completeness sake
    innerArgs.RoutedEvent = args.RoutedEvent;
    innerArgs.Handled = args.Handled;
    innerArgs.Source = args.Source;
    handler.Invoke( sender, innerArgs );
};
RoutedUICommand cmd = new RoutedUICommand( "Temp", "Temp", this.GetType() );
newItem.CommandBindings.Add( new CommandBinding(cmd, executed) );
newItem.Command = cmd;

您可能需要更换

this.GetType()

根据您构建菜单项的上下文,使用其他内容。我认为它必须是对象的类型,它将成为可视树中 MenuItem 的最终父对象(在我的情况下,是我正在复制其上下文菜单项的对象)。

于 2011-07-18T16:18:45.913 回答