将RoutedEvent处理程序从一个控件复制到另一个控件

时间:2011-07-18 12:02:29

标签: wpf routed-events

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

我已经看到了在Windows窗体中执行此操作的代码(例如Is it possible to "steal" an event handler from one control and give it to another?),但我无法找到WPF路由事件的解决方案。

1 个答案:

答案 0 :(得分:0)

当我需要在WPF中复制菜单项时,我按照建议使用命令模式,但是通过一些聪明的技巧,你仍然可以支持事件处理程序(详见下文)。我用来复制项目的代码看起来像这样,其中“item”是我正在复制的旧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对象(预订),你可以做这个小工作(其中“handler”是我正在包装的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的最终父对象的对象类型(在我的例子中是我正在复制的上下文菜单项的对象)。

相关问题