- •А.А. Волосевич
- •1. ОбщееописаниеWpf
- •2. ПРостейшее ПриложениеWpf
- •4. Базовые концепции wpf Иерархия классов
- •Свойства зависимостейи присоединённые свойства
- •Маршрутизируемыесобытия
- •Многопоточность в wpf
- •5. СтруктуРа Оконного приложения wpf
- •Класс Window
- •КлассApplication
- •6. Компоновка
- •Размер и выравнивание
- •Основные контейнеры компоновки
- •Прокрутка и декорирование содержимого
- •7. Обзор элеменТов управления
- •Цвета и окантовка:
- •Шрифт содержимого:
- •Элементы управления содержимым
- •Списковые элементы управления
- •Прочие элементы управления
- •8. Фигуры
- •9. Цвет,кисти, прозрачность Представление цвета в wpf
- •Лучшие кисти
- •Прозрачность
- •10. Трансформации и эффекты
- •11. Классы drawing иvisual
- •12. Ресурсы
- •Двоичные ресурсы
- •Логические ресурсы
- •13. Привязка данных Базовые концепции привязки данных
- •Практическое использование привязки данных
- •Конвертеры значений
- •Проверка данных
- •14. Стилии триггеры
- •15. ПрИвязкакколлекциямиШаблоныданных
- •16. Представления Данных
- •17. ШАблоны элементов управления
Маршрутизируемыесобытия
Маршрутизируемые события (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–булево свойство; позволяет узнать, выполняется ли операция.