WPF Routed Event, подписка на пользовательские события
Я пытаюсь заставить перенаправленные события работать с дочерними элементами управления, которые будут вручную запускать эти события, и они будут пузыриться и обрабатываться на уровне основной сетки. Я в основном хочу сделать что-то вроде этого:
<Grid Name="Root" WpfApplication5:SpecialEvent.Tap="Catcher_Tap">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<WpfApplication5:UserControl2 Grid.Row="0" x:Name="Catcher" />
<WpfApplication5:UserControl1 Grid.Row="1" />
<Frame Grid.Row="2" Source="Page1.xaml" />
</Grid>
Но когда я запускаю свой пример, я получаю нулевую ссылку в структуре представления, приложение никогда не инициализируется, оно терпит неудачу, когда оно пытается загрузить / инициализировать XAML (InitializeComponent()). Вот небольшой файл, который содержит событие:
public class SpecialEvent
{
public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent(
"Tap", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(UserControl1));
// Provide CLR accessors for the event
public event RoutedEventHandler Tap;
}
Я в основном хочу скопировать поведение того, как ButtonBase.Click позволяет родителям подписываться на любые методы click() для своих детей. Но, похоже, это не работает ни для чего, кроме ButtonBase.Click(). То есть когда я выключаю свой кастом WpfApplication5:SpecialEvent.Tap="Catcher_Tap"
в ButtonBase.Click="Catcher_Tap"
оно работает. Есть идеи почему? Что делает ButtonBase, а я нет?
2 ответа
Поиграв еще немного, я обнаружил, что можно выполнить то, что мне нужно, в коде позади главного окна, например, так:
public MainWindow()
{
InitializeComponent();
Root.AddHandler(SpecialEvent.TapEvent, new RoutedEventHandler(Catcher_Tap));
}
По какой-то причине указание его в XAML, как вы бы сделали для ButtonBase() , не работает, но добавление Handler
в коде позади делает.
Код, который вы указали, регистрирует пользовательское событие, но не регистрирует прикрепленное пользовательское событие. Вы должны будете явно реализовать Add*Handler
а также Remove*Handler
методы, если вы хотите использовать прикрепленный синтаксис с вашим событием. См. Раздел "Определение собственных вложенных событий как маршрутизируемых событий" в этой статье MSDN.