Скопируйте обработчик RoutedEvent из одного элемента управления в другой
У меня есть WPF MenuItem, возвращенный из функции без какой-либо информации, и я хочу установить другое (новое) событие щелчка MenuItem такой же функцией, что и первый MenuItem.
Я видел код для этого в формах Windows (например, можно ли "украсть" обработчик событий из одного элемента управления и передать его другому?), Но я не могу найти решение для перенаправленных событий WPF.
1 ответ
Когда мне нужно скопировать пункты меню в 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 (предварительная подписка), вы можете сделать этот небольшой обходной путь (где "обработчик" - это экземпляр 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 в визуальном дереве (в моем случае это объект, чьи пункты контекстного меню я копирую).