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, чего не делаю я?


person landoncz    schedule 27.07.2012    source источник


Ответы (2)


Поиграв еще немного, я обнаружил, что можно выполнить то, что мне нужно, в коде позади главного окна, например:

public MainWindow()
    {
        InitializeComponent();
        Root.AddHandler(SpecialEvent.TapEvent, new RoutedEventHandler(Catcher_Tap));
    }

По какой-то причине указание его в XAML, как для ButtonBase(), не работает, но добавление Handler в код работает.

person landoncz    schedule 27.07.2012

Предоставленный вами код регистрирует пользовательское событие, но не регистрирует прикрепленное пользовательское событие. Вам придется явно реализовать методы Add*Handler и Remove*Handler, если вы хотите использовать прикрепленный синтаксис с вашим событием. См. раздел «Определение собственных вложенных событий как перенаправленных событий» в этой статье MSDN.

person Nathan Friend    schedule 11.10.2013