Пользовательские элементы управления
Учебный элемент. Создание пользовательского элемента управления средствами дизайнера Expression Blend
В предыдущем учебном элементе мы рассмотрели, как создавать новый пользовательский элемент управления при помощи диалогового окна VS 2010 "Add New Item" (добавить новый элемент) с последующим построением UI. Такой способ работы идеален в случае, если вы представляете, как должен выглядеть UI. Также эту задачу можно выполнить и при помощи Expression Blend.
Шаг 1. Инкапсуляция UI в User Control
В данном примере, мы работаем над формой, который будет позволять прикреплять пользователям информацию об адресах доставки и выставления счета (рис. 10.6). Можно начать с создания некоторого UI, который будет принимать информацию об адресе. Чтобы это сделать, мы добавим на страницу элемент правления <border> и поместим в него gird layout panel (2 колонки по 4 ряда), а затем поместим labels (метки) и textbox (текстовые поля) там же:
Можно использовать "Add New Item" (добавить новый элемент), затем в пустой шаблон контрола при помощи копирования переместить уже собранный UI.
В Blend можно сделать еще проще – выбираем нужные для инкапсуляции элементы управления в дизайнере и после щелчка правой кнопкой мыши в появившемся меню щелкаем "Make Control" (сделать элементом управления, рис. 10.7):
При этом Blend попросит задать имя для нового юзер-контрола (рис. 10.8):
Назовем его "AddressUserControl" и нажимаем ОК. Появится новый юзер-контрол, содержимое которого будет идентично ранее выделенному (рис. 10.9 ):
Когда мы пересоберем весть проект и дойдем до первоначальной страницы, то увидим тот же UI, за исключением того, что пользовательский интерфейс адреса "зашит" в наш AddressUserControl (рис. 10.10 ):
Мы можем переименовать 1 - ый AddressUserControl в "ShippingAddress" (дословно - адрес доставки), а вторую копию превратить в "BillingAddress" (досл. - адрес выставления счета) и использовать их обоих соответственно названиям (рис. 10.11 ).
А если мы хотим изменить внешний вид, то изменения будут проводиться единократно и сразу для обоих адреса доставки и выставления счета.
Шаг 2. Привязка адресов к нашему AddressUserControl – контроллеру
Поскольку с инкапсуляциями покончено, давайте построим класс - модель для вводимой информации (в нашем случае адреса). Зададим класс (рис. 10.12 ) пользуясь удобной функцией "автоматические свойства":
В режиме просмотра кода нашего файла Page.xaml мы сразу увидим оба наших объекта (ShippingAddress" и "BillingAddress"), первый будет служить для вставки адресата доставки, а второй – адресата выставления счета (в данном случае мы просто заполним строки "пустой" информацией). Затем привяжем объекты – адреса к нашим элементам управления на странице (рис. 10.13). Сделаем мы это, используя свойство "DataContext", задавая каждому контролу свою модель (1-му- адрес доставки, 2-му – адрес счета):
Последним шагом будет добавление выражения {Binding} (привязка) в нашем AddressUserControl.xaml файле, что обеспечит двустороннюю связь между свойствами текста в TextBox и созданной нами моделью информации – адреса, закрепленной нами в качестве контроллера (рис. 10.14 ):
При нажатии F5 для запуска приложения мы увидим, что они связаны (рис. 10.15 ):
Поскольку мы задали двустороннюю связь (используя "Mode=TwoWay"), то изменения, вносимые пользователями, будут без специального кода вноситься в модель. Например, мы захотели поменять исходный адрес на адрес Диснейленда:
Устанавливаем breakpoint (рис. 10.16) на обработчик "Click" кнопки "Save" (затем на неё нажмём) и видим, как с изменением содержимого TextBox меняется и наша модель "_shippingAddress":
Потом можно также реализовать обработчик событий SaveBtn_Click, чтобы фиксировать модели так, как мы хотим, при этом пальцем не притрагиваясь к UI. Это четкое разделение модели и представления, представленное WPF и поддерживаемое Silverlight, позволяет и в дальнейшей работе изменять UI адрес – модуля без внесения каких–либо изменений в сам код. Также это упрощает тестовый прогон работоспособности программы.
Краткие итоги
WPF и Silverlight позволяют легко проводить инкапсуляцию функций UI в элементах управления, и поддерживаемая ими механика пользовательского управления только способствует этому. Привязка вкупе с пользовательским элементом управления создают границу между моделью/представлением, что позволяет написать рациональный код при работе с информацией.