Главная » WPF » Принципиальные основы действий

0

В том, что касается действий, WPF опирается на три принципа, которые на са мом деле служат  естественным  продолжением тех, что мы уже рассматривали: композиция элементов,  слабая связь и декларативное описание.  Для того чтобы действия  были совместимы  со способом построения  дерева отображения, в кото ром одни элементы включают в себя другие, композиция является непременным условием.  Тот факт,  что элемент  управления может радикально  изменить  свой внешний  облик, порождает  сложности  в случае, когда источник  события  и код его обработки  тесно связаны  между  собой; поэтому  механизм  ослабления этой связи  также необходим.  И, наконец,  поскольку  декларативная модель програм мирования пронизывает всю систему, WPF обязана поддерживать и декларатив ную обработку действий тоже.

Композиция элементов

В главе 3 мы убедились,  что кнопка  на самом деле составлена  из нескольких элементов. Из за наличия  подобной композиции возникает  интересная  проблема при обработке  событий.  Напомним три принципа  построения  элементов  управ ления: композиция элементов, повсеместность развитого содержимого  и простая модель программирования.

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

Button b = new Button();

b.Content = «Click Me»;

b.Click += delegate { MessageBox.Show(«You clicked me!»); };

На первый взгляд, выглядит замечательно, но посмотрим, что тут реально происходит.  Ведь щелкаем мы не по кнопке, а по какому  то из элементов,  из ко торых  кнопка  составлена.  Чтобы  все работало  гладко, в WPF введено  понятие маршрутизации события, которое позволяет  обойти составляющие элементы. Продемонстрировать его мы сможем, добавив в предыдущем примере вторую кнопку, которая будет выступать в качестве содержимого. Щелчок как по первой, так и по второй кнопке приводит к возбуждению  события:

Button b = new Button();

b.Content = new Button();

b.Click += delegate { MessageBox.Show(«You clicked me!»); };

Получающееся дерево отображение  показано  на рис. 7.1, из которого  также видно, что нам следует озаботиться не только двумя кнопками.  Даже в простом случае единственной кнопки  композиция событий  необходима  для того, чтобы маршрутизировать событие мыши до кнопки.

Композиция элементов  отражается  на всех аспектах обработки действий, а не только на событиях.

Слабая связь

Из описания  событий  в интерфейсе  класса Button следует, что он поддержи вает не только непосредственные события  мыши (MouseUp, MouseDown и т.д.), но и событие Click, которое является абстракцией гораздо более высокого уров ня, чем просто событие мыши. Оно возникает  и тогда, когда пользователь нажи мает пробельную  клавишу  (при условии,  что кнопка владеет фокусом) или кла вишу Enter (если это кнопка по умолчанию для окна). Нажатие  кнопки – это се мантическое событие, тогда как события мыши относятся  к физическим.

Рис. 7.1. Дерево отображения (слева) кнопки, в которую вложена другая кнопка (справа)

У написания кода для обработки именно события Click есть два преимущест ва: (1) мы не привязываемся к конкретному жесту пользователя (операции с мышью или клавиатурой) и (2)  мы не ограничиваем  себя только кнопкой.  Каж дый из элементов  CheckBox,  RadioButton, Button и Hyperlink поддерживает на жатие. Если обработчик связан с событием Click, то он применим  к любому ком поненту, который может быть «нажат». Такое отделение кода от действия обеспе чивает большую гибкость в реализации обработчиков.

Однако самим событиям присуща некая форма зависимости; требуется, чтобы метод обработчик  имел вполне определенную сигнатуру. Например, делегат для обработки события Button.Click определен следующим образом:

public delegate void RoutedEventHandler(object sender, RoutedEventArgs e);

Одна из целей WPF – поддержать широкий спектр действий (рис. 7.2): от тес но связанных физических событий  (например, MouseUp) до чисто семантичес ких извещений  (например, команды ApplicationCommands.Close, которая  сигна лизирует  о том, что окно должно быть закрыто).

Допуская  слабую связь, мы получаем возможность писать шаблоны, которые радикально  меняют элемент управления. Например, включив кнопку, ассоци ированную с командой Close, мы сможем написать шаблон для окна, который до бавляет элемент для закрытия:

<ControlTemplate TargetType=’{x:Type Window}’>

<DockPanel>

<StatusBar DockPanel.Dock=’Bottom’>

<StatusBarItem>

<Button

Command=’{x:Static ApplicationCommands.Close}’>

Close

</Button>

</StatusBarItem>

</StatusBar>

<ContentPresenter />

</DockPanel>

</ControlTemplate>

Теперь можно заставить окно закрываться, когда любой компонент пошлет коман

ду Close; для этого достаточно добавить в код класса окна соответствующую привязку:

public MyWindow() { InitializeComponent();

CommandBindings.Add(

new CommandBinding( ApplicationCommands.Close, CloseExecuted

)

);

}

void CloseExecuted(object sender, ExecuteRoutedEventArgs e) {

this.Close();

}

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

Источник: К. Андерсон  Основы  Windows Presentation Foundation. Пер. с англ. А. Слинкина — М.: ДМК Пресс, 2008 — 432 с.: ил.

По теме:

  • Комментарии