Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Windows Presentation Foundation.docx
Скачиваний:
12
Добавлен:
13.08.2019
Размер:
1.13 Mб
Скачать

Маршрутизируемыесобытия

Маршрутизируемые события (routedevents) – модель событий WPF, созданная для использования в дереве визуальных элементов. При генерации маршрутизируемого события информация о нём может быть передана как родительским, так и дочерним элементам источника событий.

Реализация и использование маршрутизируемых событий имеет много общего со свойствами зависимостей. Рассмотрим в качестве примера реализацию события Clickв элементе управления Button:

publicclassButton : ButtonBase

{

// статическое поле для маршрутизируемого события

publicstaticRoutedEventClickEvent=

EventManager.RegisterRoutedEvent("Click",

RoutingStrategy.Bubble,

typeof(RoutedEventHandler),

typeof(Button));

// экземплярнаяоболочкасобытия

publiceventRoutedEventHandler Click

{

add { AddHandler(ClickEvent, value); }

remove { RemoveHandler(ClickEvent, value); }

}

// внутреннийметоддлягенерациисобытия

protectedoverridevoidOnClick(EventArgse)

{

RaiseEvent(newRoutedEventArgs(ClickEvent, this));

}

}

МетодыAddHandler(),RemoveHandler()иRaiseEvent() – этометодыклассаUIElement. Листинг показывает, что при регистрации маршрутизируемого события используется метод EventManager.RegisterRoutedEvent(). Одним из аргументов метода является элемент перечисления RoutingStrategy, описывающего стратегию маршрутизации события:

  • Tunnel – событие генерируется в корневом элементе, затем в каждом дочернем элементе, пока не будет достигнут элемент-источник.

  • Bubble – событиегенерируетсявэлементеисточнике, затемвкаждомродительскомэлементе, вплотьдокорнядереваэлементов.

  • Direct – событиегенерируетсятольковэлементе-источнике.

Обработчики маршрутизируемых событий принимают аргумент RoutedEventArgs. Этот класс содержит четыре полезных свойства:

  • Source – источник события в логическом дереве элементов;

  • OriginalSource – источник события в визуальном дереве элементов;

  • Handled – это значение можно установить в true для остановки маршрутизации события в дереве;

  • RoutedEvent – объект, описывающий маршрутизируемое событие.

КлассUIElementопределяетмножествомаршрутизируемыхсобытий, связанных с клавиатурой, мышью, стилусом. БольшинствособытийиспользуютBubble-стратегию. МногиеBubble-события имеют сопряжённое Tunnel-событие, которое генерируется перед Bubble-событием (Tunnel-событие отличает префикс Preview в названии).

Многопоточность в wpf

Элементы WPF, отображаемые в одном окне, обладают потоковым родством (thread affinity). Это означает, что поток, который создал их, владеет ими,а другие потоки не могут взаимодействовать с этими элементами напрямую1.

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

  • Dispatcher – свойство, возвращающее диспетчер потока;

  • CheckAccess()– метод, который возвращает true, если код находится в потоке элемента;

  • VerifyAccess() – если вызывающий код находится не в потоке элемента, данный метод генерирует исключение InvalidOperationException.

Диспетчер– это экземпляр класса System.Windows.Threading.Dispatcher. Метод диспетчера BeginInvoke() используется для того, чтобы спланировать код в качестве задачи для диспетчера:

// предположим, что это обработчик нажатия некоторой кнопки

privatevoid btn_Click(object sender, RoutedEventArgs e)

{

newThread(UpdateTextRight).Start(); // запускаемновыйпоток

}

privatevoid UpdateTextRight()

{

Thread.Sleep(3000); // имитируемработу

// обновим интерфейс

// для этого получаем ссылку на диспетчер (у текущего окна)

// а затем используем метод BeginInvoke()

Dispatcher.BeginInvoke(DispatcherPriority.Normal,

(Action)(() =>txt.Text = "Новыйтекст"));

}

Для организации в приложении WPFасинхронного выполнения можно использовать объект класса System.ComponentModel.BackgroundWorker.Перечислим основные элементы этого класса.

  • RunWorkerAsync()– вызов метода начинает выполнение асинхронной операции. Имеется перегруженная версия, принимающая параметр асинхронной операции (аргумент типа object).

  • CancelAsync()– вызов метода означает запрос на отмену асинхронной операции.

  • DoWork–событие; его обработчик становится асинхронной операцией.

  • RunWorkerCompleted– это событие генерируется, если асинхронная операция завершилась, была отменена или прекращена из-за исключения.

  • IsBusy–булево свойство; позволяет узнать, выполняется ли операция.