Разработка пользовательского элемента управления
Работы в Blend окончены, выберем в нём команду Файл > Сохранить всё и вернемся в Visual Studio. Всё то, что мы делали в Blend, привело к изменениям в XAML-разметке, в Листинге 13.3 приведен код файла MyControl.xaml.
<UserControl x:Class="P3_1.MyControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" d:DesignHeight="480" d:DesignWidth="480" Width="356" Height="64"> <UserControl.Resources> <Storyboard x:Name="ProgressStoryboard"> <DoubleAnimation Duration="0:0:2" To="0.001" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="rectangle" d:IsOptimized="True"/> <DoubleAnimation Duration="0:0:2" To="176.667" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="rectangle" d:IsOptimized="True"/> <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill). (SolidColorBrush.Color)" Storyboard.TargetName="rectangle"> <EasingColorKeyFrame KeyTime="0" Value="#FF410DF5"/> <EasingColorKeyFrame KeyTime="0:0:2" Value="#FF42DC20"/> </ColorAnimationUsingKeyFrames> </Storyboard> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}"> <Rectangle x:Name="rectangle" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="44" VerticalAlignment="Top" Width="355" Margin="0,10,0,0" RenderTransformOrigin="0.5,0.5"> <Rectangle.RenderTransform> <CompositeTransform/> </Rectangle.RenderTransform> </Rectangle> </Grid> </UserControl>Листинг 13.3. Код файла MyControl.xaml после работы в Blend
В разметке мы видим описание раскадровки ProgressStoryboard, в области содержимого можно видеть код описания прямоугольника.
Уже сейчас мы можем добавить элемент управления на страницу приложения. Он автоматически отображается в Панели элементов, добавление его на страницу выглядит точно так же, как добавление обычных элементов. После добавления элемента на стартовую страницу приложения, дадим ему имя MyControlMainPage (рис. 13.7). Если запустить сейчас наш проект для отладки, окажется, что элемент управления выводится, содержит прямоугольник белого цвета, но не реагирует на воздействия пользователя. Так и должно быть – мы не создавали пока механизмы по его взаимодействию с пользователем и с другими элементами приложения.
Поработаем с кодом элемента управления
Для начала зададим обработчик события DoubleTap для сетки LayoutRoot. В обработчике запустим анимацию командой ProgressStoryboard.Begin(). Если запустить сейчас проект для отладки, окажется, что элемент управления реагирует на двойное касание, меняя цвет и запуская анимацию изменения размера и изменения цвета.
Для того, чтобы можно было выводить с его помощью сообщение, текст которого можно настраивать, добавив в код его класса (в файле MyControl.xaml.cs) общедоступное свойство строкового типа с именем Message, указав возможность его чтения и установки извне и опишем событие ReadyToLoadPage.
Мы будем вызывать это событие, предварительно показав пользователю окно сообщения, после того, как завершится исполнение раскадровки. Для этого нам понадобится обработать событие раскадровки Completed, которое вызывается при её завершении. В итоге мы пришли к такому коду файла MyControl.xaml.cs, Листинг 13.4
using System; using System.Windows; using System.Windows.Controls; namespace P3_1 { public partial class MyControl : UserControl { public event EventHandler ReadyToLoadPage; public string Message { get; set; } public MyControl() { InitializeComponent(); } private void LayoutRoot_DoubleTap(object sender, System.Windows.Input.GestureEventArgs e) { ProgressStoryboard.Begin(); } private void ProgressStoryboard_Completed(object sender, EventArgs e) { if (Message!=null) MessageBox.Show(Message); ReadyToLoadEventCall(); } private void ReadyToLoadEventCall() { if (this.ReadyToLoadPage != null) this.ReadyToLoadPage(new object(), new EventArgs()); } } }Листинг 13.4. Код файла MyControl.xaml.cs
Здесь мы, при обработке события завершения раскадровки ProgressStoryboard_Completed проверяем, задано ли свойство Message. Если задано – выводим сообщение. Приложение ожидает реакции пользователя на сообщение, когда пользователь отреагировал, вызывается метод ReadyToLoadEventCall. В этом методе мы проверяем, подключён ли обработчик события, и если это так – вызываем событие. При обработке события нам важно то, что оно произойдёт, поэтому передача параметров носит формальный характер.
После подобных изменений в пользовательском элементе управления для нормальной работы с ним на страницах приложения нужно перестроить проект.
Добавим в проект еще одну страницу (контекстное меню проекта, команда Добавить > Создать элемент > Страница Windows Phone в книжной ориентации, дадим ей имя NextPage.xaml).
На странице MainPage.xaml мы можем, во-первых, задать свойство элемента управления Message, запишем туда текст "Теперь можно продолжать!". Это свойство, как и при работе с обычными элементами управления, доступно в панели свойств. При группировке свойств по категориям оно будет находиться в категории Разное. Так же, зададим обработчик события ReadyToLoadPage (рис. 13.8.), оно будет перечислено среди прочих событий элемента управления, которые мы можем обрабатывать на странице приложения, для создания обработчика достаточно выполнить двойной щелчок по соответствующему полю.