| Украина |
Пользовательские элементы управления
Шаг 2. Добавление обработки событий клавиатуры
Для реализации функциональности "быстрых клавиш" нам необходимо осуществить реакцию на события клавиатуры, полученные элементом StackPanel, в частности событие KeyDown. Событие KeyDown является пузырьковым событием.
Мы можем начать с простого и отвечать на любые события клавиатуры путем заполнения формы адресом компании Microsoft. Присвоим классу защищенный объект (private) Address, который мы инициализируем в конструкторе. Также будем обрабатывать стандартное событие Loaded, которое вызывается при загрузке страницы.
public partial class MainPage : UserControl
{
private Address theAddress;
public MainPage()
{
InitializeComponent();
address = new Address();
Loaded += new RoutedEventHandler(OnLoaded);
}В OnLoaded мы хотим создать обработчик события для KeyDown при регистрации любого события клавиши для любого элемента управления в пределах табличной сетки, которую мы назвали AddressGrid в MainPage.xaml следующим образом,
<Grid x:Name="AddressGrid" Background="Bisque" >
При сохранении страницы MainPage.xaml данный определитель мгновенно будет доступен в фоновом коде, и мы можем получить доступ к его свойствам и событиям, включая событие KeyDown.
void OnLoaded(object sender, RoutedEventArgs e)
{
AddressGrid.KeyDown += new KeyEventHandler(AddressGrid_KeyDown);
}Visual Studio 2010 предложит вам создать программную оболочку для обработчика события, что нам как раз и нужно. Нам необходимо заполнить форму адресом компании Microsoft при нажатии Ctrl+M.
void AddressGrid_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.M && Keyboard.Modifiers == ModifierKeys.Control)
{
address.Location = "Microsoft";
address.Address1 = "One Microsoft Way";
address.Address2 = "Building 10";
address.City = "Redmond, WA 98052";
}
this.DataContext = theAddress;
} Обратите внимание на то, что мы завершаем событие установкой DataContext страницы в только что заполненный объект Address. Результатом будет объект для привязки к элементам управления.
Шаг 3. Инкапсуляция разметки и логики в элемент управления UserControl
На самом деле, нам наверняка понадобится наличие домашнего адреса (Home Address), рабочего адреса (Work Address) и адреса выставления счета (Billing Address), и неплохо было бы иметь комбинацию клавиш для каждого из адресов. Это можно реализовать двумя способами:
- продублировать xaml на стартовой странице нашего приложения и его фоновый код для каждого экземпляра (home, work, billing);
- перестроить (инкапсулировать) ранее созданную разметку и код в независимый элемент управления (отдельный UserControl).
Разумный подход - инкапсулировать стандартный xaml и поддерживающий код в элемент управления путем создания пользовательского элемента управления (UserControl).
Добавим в проект Silverlight User Control. Назовем новый элемент управления AddressUserControl.xaml.
К проекту будут добавлены два файла
- AddressUserControl.xaml
- AddressUserControl.xaml.cs
AddressUserControl.xaml выглядит очень знакомо при открытии.
<UserControl x:Class="ControlsExample.AddressUserControl"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
…
</Grid>
</UserControl>Реализация элемента управления
Вернемся к MainPage.xaml и вынесем xaml разметку начиная с Border во вновь созданный UserControl, заменив табличную сетку, созданную там Visual Studio 2010.
Обратите внимание на то, что ваш элемент управления находится в правильном месте, но немного узок. Удалите атрибуты ширины (Width) и высоты (Height) и внешнего пользовательского элемента управления,
<UserControl x:Class="ControlsExample.AddressUserControl"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
> <!--no specific size-->
<Border BorderBrush="Black" BorderThickness="1" Margin="15">
…
Как только вы удалите их, элемент управления будет выровнен по центру, а также расширен для того, чтобы вместить в себя элементы управления (рис. 9.2).
Добавление кода
Все последующие шаги выполняются в AddressUserControl.xaml.cs: Добавляем переменную экземпляра Address так же, как и в MainPage.xaml.cs. В конструкторе выделяем память для объекта Address и настраиваем обработчик события Loaded. В реализации OnLoaded добавляем новый обработчик для события KeyDown табличной сетки.
public partial class AddressUserControl : UserControl
{
private Address theAddress = null;
public AddressUserControl()
{
InitializeComponent();
theAddress = new Address();
Loaded += new RoutedEventHandler(OnLoaded);
}
void OnLoaded(object sender, RoutedEventArgs e)
{
AddressGrid.KeyDown += new KeyEventHandler(AddressGrid_KeyDown);
}Реализация AddressGrid.KeyDown была вырезана из MainPage.xaml.cs
void AddressGrid_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.M && Keyboard.Modifiers == ModifierKeys.Control)
theAddress.Location = "Microsoft";
theAddress.Address1 = "One Microsoft Way";
theAddress.Address2 = "Building 10";
theAddress.City = "Redmond, WA 98052";
}
this.DataContext = theAddress;
}
}Использование пользовательского элемента управления
Мы завершили создание пользовательского элемента управления, но от него нет толку, пока вы его не расположите в файле MainPage.xaml. В самой верхней части MainPage.xaml добавьте пространство имен для вашего AddressUserControl’a:
xmlns:controls="clr-namespace:ControlsExample"
Теперь вы можете заменить ваш пользовательский элемент управления для всего содержимого Border в MainPage.xaml. Если вы еще не удалили Border, то удалите и замените своим элементом управления, точно также как вы вставили бы любой другой элемент управления в StackPanel,
<controls:AddressUserControl x:Name="HomeAddress" />
Многократное использование
Давайте добавим еще один пользовательский элемент управления к StackPanel и изменим подсказки таким образом, чтобы у нас было следующее
<UserControl x:Class="Example.MainPage"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:ControlsExample"
Width="600" Height="500">
<StackPanel Background="White">
<TextBlock Text="Event Address" FontFamily="Verdana" FontSize="24"
HorizontalAlignment="Left" Margin="15,0,0,0"/>
<controls:AddressUserControl x:Name="HomeAddress" />
<TextBlock Text="Billing Address" FontFamily="Verdana" FontSize="24"
HorizontalAlignment="Left" Margin="15,0,0,0"/>
<controls:AddressUserControl x:Name="BillingAddress" />
</StackPanel>
</UserControl> Обратите внимание, что добавление второго экземпляра AddressUserControl требует только наличия двух различных названий. Более того мы смогли вынести весь код из главной страницы приложения (логика которого не относилась к MainPage.xaml.cs)
using System.Windows.Controls;
namespace Example
{
public class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
}
}Вся логика была экспортирована и инкапсулирована в пользовательском элементе управления. Вы можете добавить 2 (или 20) пользовательских элемента управления AddressUserControl в ваш интерфейс, не написав и строки кода. При этом, запустив программу, каждый элемент будет работать независимо и каждый поддерживает комбинацию Ctrl + M
