1

Тема: Маршрутизируемые события в Silverlight

Маршрутизируемые события в Silverlight
Routed Events in Silverlight

С появлением Windows Presentation Foundation появился новый тип событий – RoutedEvents. Они открыли разработчикам совершенно новый подход к работе с событиями. Для тех, кто хорошо знаком с WPF и маршрутизацией событий могут посчитать эту статью бесполезной, но я уверен, что она может быть хорошей отправной точкой для всех, кто делает свои первые шаги в маршрутизации событий, особенно если это касается Silverlight.

Thumbs up Thumbs down

2

Re: Маршрутизируемые события в Silverlight

Основы маршрутизации событий

Прежде чем начать объяснение маршрутизируемых событий вы должны разобраться с деревом элементов (еще его называют визуальным деревом), которое является типичным для любого WPF или Silverlight приложения. Оно состоит из контролов приложения и их статуса относительно друг друга как родительских или дочерних элементов. Например:

<UserControl>
    <Grid>
        <StackPanel>
            <TextBlock />
            <TextBox />
            <Button />
        </StackPanel>
    </Grid>
</UserControl>

Маршрутизируемые события непосредственно связаны с визуальным деревом. Событие распространяется по этому дереву вверх или вниз, так что событие может быть поймано контролом, который его не порождал.

Существует три типа RoutedEvents: прямые, туннелированные и всплывающие.

Прямые (Direct)

Этот тип события может быть пойман только тем контролом, который возбудил данное событие. Данный тип события очень напоминает хорошо знакомые события из WinForms и ASP.NET.

Туннелированные (Tunneling)

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

Всплывающие (Bubbling)

Этот тип событий в первую очередь отлавливается источником своего появления, затем всеми родительскими элементами, пока не будет достигнут корневой элемент визуального дерева.

Свойство Handled

Одним из основных признаков всех маршрутизируемых событий является присутствие среди его аргументов свойства Handled. Если в обработчике события задать этому свойству значение true, это остановит его дальнейшее распространение по дереву элементов.

Thumbs up Thumbs down

3

Re: Маршрутизируемые события в Silverlight

RoutedEvents в Silverlight

То, что объяснялось выше, полностью работает в WPF, но в Silverlight имеются небольшие отличия. Вот наиболее важные из них:

•    В Silverlight вы не можете создавать пользовательские RoutedEvents. В WPF для создания пользовательского события этого типа вы можете использовать EventManager, но в Silverlight это невозможно. Существует способ обойти это ограничение, но мы поговорим об этом немного позже.
•    В Silverlight поддерживается только всплывающий тип событий. Это такие события, как MouseLeftButtonDown и MouseLeftButtonUp.
•    Специфические для определенных контролов события не «всплывают», например событие Click контрола Button. И это довольно логично, ибо зачем распространять событие по дереву элементов, если оно может быть обработано только определенным видом контролов?

Вот небольшой пример (и исходный код к нему), который продемонстрирует поведение всплывающих событий в Silverlight. В примере я использовал события MouseLeftButtonUp и MouseLeftButtonDown.

Когда я обрабатываю событие MouseLeftButtonUp я вывожу имя контрола, поймавшего это событие в информационный список, а по событию MouseLeftButtonDown я очищаю этот список. При обработке обоих этих событий в контроле ListBox я выставляю их свойство handled в true, поскольку мне не нужно, чтобы события, порожденные этим контролом, распространялись дальше по дереву элементов. Тоже самое я сделал для обработчика события MouseLeftButtonDown, т.к. список не нуждается более, чем в одной очистке.

Замечание! Используйте маршрутизируемые события только там, где это необходимо и не забывайте останавливать такие события, если нет нужды распространять их по все дереву элементов, поскольку это может привести к логическим ошибкам в результате ложных срабатываний обработчиков других контролов. Допустим,  LayoutRoot прослушивает события порожденные определенным элементом визуального дерева (прямоугольником), но это же событие может быть порождено любым другим элементом дерева (например, в LixtBox). Если мы позволим событию, порожденному в ListBox распространиться до LayoutRoot, тогда оно будет им поймано, что приведет к некорректному поведению приложения.

Thumbs up Thumbs down

4

Re: Маршрутизируемые события в Silverlight

Telerik RadControls для Silverlight и EventManager

Если вы еще не знаете, Telerik RadControls для Silverlight реализуют маршрутизируемые события точно так же, как в WPF. Почти все используемые там события являются RoutedEvents, и возможно у вас возникнет вопрос, как они сделали пользовательские RoutedEvents, если Silverlight не поддерживает создание пользовательских RoutedEvents. Чтобы преодолеть это ограничение они добавили в свои контролы новые типы: EventManager, RoutedEvent и RoutingStrategy. Тем, кто хорошо знает WPF, эти типы не будут сюрпризом. Вся функциональность точно скопирована с WPF, поэтому их использование в Silverlight будет идентичным. Если у вас уже есть под рукой RadControls и вам нужно, чтобы приложение поддерживало пользовательские события, вы можете воспользоваться этим решением. Если вы хотите узнать больше об этом, прочитайте пост от HristoHristov’а.

Thumbs up Thumbs down

5

Re: Маршрутизируемые события в Silverlight

Заключение

Маршрутизируемые события – очень мощный механизм, который может улучшить функциональность наших приложений. Существуют некоторые различия между ними в Silverlight и WPF, но давайте все же не будем забывать, что Silverlight – это подмножество WPF и ему еще предстоит долгий путь развития. Но я был довольно сильно впечатлен всплывающими событиями и уверен, что найду их полезными в моих будущих приложениях.

Thumbs up Thumbs down

6

Re: Маршрутизируемые события в Silverlight

Ссылки

Джесси Либерти – прекрасная серия статей о RoutedEvents и Silverlight. Статьи написаны для версий Silverlight Beta 1 и Beta 2, но, даже несмотря на это, они мне очень пригодились:

http://silverlight.net/blogs/jesseliber … d-not.aspx
http://silverlight.net/blogs/jesseliber … bling.aspx
http://silverlight.net/blogs/jesseliber … bling.aspx

Христо Христов и его пост о EventManager из Telerik RadControls для Silverlight:

http://blogs.telerik.com/HristoHristov/ … ght_2.aspx

И статья на MSDN о RoutedEvents в WPF:

http://msdn.microsoft.com/en-us/library … S.85).aspx

Thumbs up Thumbs down