Построение классов UserControl

45

Давайте рассмотрим, каким образом в среде Expression Blend упрощается построение полнофункциональных классов UserControl. Вам, возможно, известно, что на платформах WPF и Silverlight понятие элемента управления реализуется в классе, инкапсулирующем коллекцию связанных вместе элементов пользовательского интерфейса. В отличие от шаблона элемента управления, применяемого к конкретному элементу управления и определяющего его внешний вид и поведение, специализированный класс UserControl представляет собой совершенно новый элемент пользовательского интерфейса, создаваемый путем агрегирования существующих элементов управления.

В меню Expression Blend имеется команда Make Into UserControl, аналогичная команде Make Into Control и доступная после выбора графического элемента на монтажном столе. Как правило, построение специализированного элемента управления класса UserControl начинается со специальной графики. Поэтому для рассмотрения примера создайте новый проект приложения WPF (или Silverlight) присвоив ему имя BlendUserControl.

Здесь и далее рассматривается проект на платформе WPF, чтобы показать на его примере особенности работы с диспетчером VSM в данном контексте.

Нарисуйте графический элемент на монтажном столе и щелкните на нем правой кнопкой мыши, чтобы выбрать команду Make Into UserControl из всплывающего контекстного меню:

Создание нового элемента управления

Присвойте подходящее имя, например OvalThoughtsControl (элемент управления выноской), вновь созданному элементу управления в открывшемся диалоговом окне:

Присвоение имени новому элементу управления

Щелкните на кнопке ОК и перейдите к панели Projects. Как показано на рисунке в текущий проект автоматически введен новый XAML-файл и связанный с ним файл исходного кода для нового элемента управления класса UserControl:

XAML-файл введенный в проект для нового элемента управления

В данном примере новый элемент управления класса UserControl автоматически построен из одного графического элемента. Но многие элементы управления данного класса обычно строятся из коллекции существующих объектов. Так, если выбрать сначала несколько графических элементов на монтажном столе, а затем команду меню Make Into UserControl, то все выбранные элементы будут сгруппированы в новый диспетчер компоновки и размещены в классе UserControl.

Если вы проанализируете разметку главного окна типа Window, то обнаружите, что исходная графика заменена экземпляром нового класса UserControl, как показано ниже:

xmlns:local="clr-namespace:BlendUserControl"

Ввод визуальных состояний

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

При создании специального элемента управления класса UserControl можно было бы, конечно, воспользоваться средой триггеров на платформе WPF, но в данном случае процесс построения такого элемента демонстрируется на примере применения диспетчера VSM.

Убедитесь в том, что активизирован монтажный стол с новым элементом управления класса UserControl, т.е. в визуальном конструкторе открыт файл разметки OvalThoughtsControl.xaml или аналогичный файл, если вы назвали новый элемент управления как-то иначе, а затем перейдите к панели States, которая должна быть в настоящий момент пуста. Щелкните на кнопке Add state group (Добавить группу состояний):

Ввод новой группы состояний в элемент кправления класса UserControl

Присвойте новой группе имя MyMouseStates, выбрав его среди стандартных имен или же введя особое имя. Аналогично рассмотренным выше группам CommonStates и FocusedStates стандартных состояний для группы специальных состояний могут быть назначены устанавливаемые по умолчанию моменты и эффекты перехода. Щелкните на кнопке Add state (Добавить состояние):

Ввод состояния в группу

Присвойте новому состоянию имя MouseOverState (состояние "наведен курсор мыши ). Обратите внимание на автоматический переход в режим регистрации данного состояния. Итак, внесите ряд изменений в свойства рассматриваемого здесь элемента управления на панели Properties и не забудьте воспользоваться панелью Objects and Timeline, чтобы быстро выбрать отдельные свойства данного элемента. Ради простоты рекомендуется вновь подобрать другой оттенок цвета заполнения геометрической формы данного элемента управления.

Введите второе (и последнее) состояние в группу MyMouseStates, присвоив ему имя MouseDownState (состояние "кнопка мыши нажата"). После этого внесите ряд изменений в рассматриваемый здесь элемент управления на панели Properties, выполнив, например, преобразование его геометрической формы. В качестве примера на рисунке приведены окончательно сформированные состояния, исходное время перехода в которые изменено до 1 секунды для всей группы специальных состояний в целом:

Сформированная группа специальных состояний

Смена состояний в коде

Если бы вы запустили на выполнение свое приложение на данной стадии его разработки, то с удивлением обнаружили бы, что ни одно из сформированных вами состояний не активизируется, как бы вы ни пытались взаимодействовать мышью с элементом управления. Дело в том, что вы пока еще не указали, когда именно должна происходить смена состояний в этом элементе. И сделать это можно двумя способами. Первый из них заключается в том, чтобы произвести смену состояний программным путем, воспользовавшись методом GoToState() из класса VisualStateManager.

Убедитесь в том, что элемент управления класса UserControl выбран на монтажном столе, перейдите к панели Properties и щелкните на кнопке Events (со знаком молнии на пиктограмме). Организуйте обработку события MouseDown как обычно, а затем введите приведенный ниже код в автоматически сформированный обработчик событий типа MouseDown:

private void OvalThoughtsControl_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			// Перейти в новое состояние
			VisualStateManager.GoToState(this, "MouseDownState", true);
		}

Первый аргумент метода GoToState() обозначает элемент управления, имеющий группы состояний. Как правило, это сам элемент управления класса UserControl. Второй аргумент данного метода обозначает имя состояния, в которое требуется перейти, а третий аргумент имеет логическое значение, указывающее, требуется ли использовать любые заранее определенные временные характеристики перехода в состояние. Еще раз запустите свое приложение на выполнение и щелкните на элементе управления. Его состояние должно измениться!

Смена состояний в разметке

Сменять состояния можно и без написания процедурного кода, используя объект поведения типа GoToStateAction. Такой способ может оказаться очень удобным при построении специальных шаблонов, которые предполагается применять во многих проектах и в то же время не загромождать ими элементы управления класса UserControl. Итак, найдите упомянутый выше объект поведения в библиотеке ресурсов:

Объект поведения GoToStateAction

Перетащите объект поведения типа GoToStateAction на элемент управления класса UserControl. (Вы можете опустить его на этот элемент непосредственно на монтажном столе или же в узле иерархического представления на панели Objects and Timeline.) Как только вы сделаете это, появится ряд объектов. Выберите объект GoToStateAction и перейдите к панели Properties, чтобы настроить соответствующее поведение.

Так, в области Trigger можно выбрать контролируемое событие (в данном случае это событие MouseEnter (Курсор мыши вошел в пределы элемента управления)). А в области Common Properties можно выбрать специальное состояние, в которое требуется перейти (в данном случае это состояние MouseOverState):

Настройа объекта поведения GoToStateAction

Вновь запустите свое приложение на выполнение и проверьте, происходит ли переход во второе состояние, когда курсор оказывается над элементом управления.

Пройди тесты
Лучший чат для C# программистов