2010-04-26 4 views
3

У меня есть пользовательский класс Button, который всегда выполняет одно и то же действие при нажатии (открытие определенного окна). Я добавляю событие Click, которое можно назначить в XAML кнопки, как обычная кнопка.Проверка наличия у RoutedEvent обработчиков

Когда он нажимается, я хочу выполнить обработчик события Click, если он был назначен, в противном случае я хочу выполнить действие по умолчанию. Проблема в том, что, по-видимому, нет способа проверить, добавлены ли какие-либо обработчики в событие.

Я думал пустой чек на событие будет делать это:

if (Click == null) 
{ 
    DefaultClickAction(); 
} 
else 
{ 
    RaiseEvent(new RoutedEventArgs(ClickEvent, this));; 
} 

... но это не компилируется. Компилятор говорит мне, что я не могу сделать ничего, кроме + = или - = для события за пределами определяющего класса, событие, хотя я пытаюсь сделать эту проверку INSIDE определяющим классом.

Я сам реализовал правильное поведение, но оно уродливое и многословное, и я не могу поверить, что нет встроенного способа сделать это. Я должен что-то упустить.

Вот соответствующий код:

public class MyButtonClass : Control 
{ 
    //... 

    public static readonly RoutedEvent ClickEvent = 
     EventManager.RegisterRoutedEvent("Click", 
             RoutingStrategy.Bubble, 
             typeof(RoutedEventHandler), 
             typeof(MyButtonClass)); 

    public event RoutedEventHandler Click 
    { 
     add { ClickHandlerCount++; AddHandler(ClickEvent, value); } 
     remove { ClickHandlerCount--; RemoveHandler(ClickEvent, value); } 
    } 

    private int ClickHandlerCount = 0; 

    private Boolean ClickHandlerExists 
    { 
     get { return ClickHandlerCount > 0; } 
    } 

    //... 
} 

ответ

1

Нет, это не возможно. Фактически, код, который вы предполагаете, обрабатывает событие непосредственно в вашем элементе управления, но вы объявляете событие Bubble, а не событие Прямое событие, поэтому технически что-то может прослушивать событие дальше по цепочке элементов. Кроме того, технически не нужно использовать событие CLR для привязки события; можно просто использовать метод AddHandler, непосредственно проходящий в вашем маршрутизируемом событии, и это то, что кто-то должен будет сделать, чтобы связать событие дальше по цепочке. Наконец, событие CLR не будет использоваться, если кто-то зарегистрирует обработчик класса для события (чтобы получать уведомление, когда это событие возбуждено для любого экземпляра вашего MyButtonClass). Если вы посмотрите на что-то вроде UIElement.BuildRouteHelper, вы увидите все шаги, которые выполняет WPF, чтобы установить маршрут события и объекты, которые будут вызваны при поднятии события.

Если вам действительно нужно знать, есть ли у вас слушатели, вам лучше создать событие только для CLR, а не маршрутизируемое событие. Затем вы можете проверить, не является ли ваш делегат не нулевым.

Смежные вопросы