Главная » Разработка для Windows Phone 7 » Маршрутизированные события Windows Phone 7

0

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

Для большей гибкости Silverlight реализует систему обработки маршрутизированных событий. Большинство событий пользовательского ввода, включая три события Manipulation, формируются соответственно парадигме, применяемой в Windows: они формируются расположенным поверх остальных активным элементом, к которому прикасается пользователь. Но если этот элемент не обрабатывает данное событие, оно передается в его родительский элемент, и так далее вверх по визуальному дереву, заканчивая элементом PhoneApplicationFrame. Любой элемент в этой цепочке может захватывать этот ввод и каким-то образом его обрабатывать, и также останавливать его дальнейшее распространение вверх по дереву.

Вот почему можно перегрузить метод OnManipulationStarted в MainPage и принимать события Manipulation для TextBlock. По умолчанию TextBlock не обрабатывает эти события.

Аргумент события ManipulationStarted – ManipulationStartedEventArgs. Он наследуется от RoutedEventArgs (Аргументы маршрутизированного события). Именно RoutedEventArgs определяет свойство OriginalSource, обозначающее элемент, который сформировал событие.

Но это предлагает другой подход, сочетающий в себе две методики, представленные в SilverlightTapHellol и SilverlightTapHello2. Рассмотрим XAML-файл проекта SilverlightTapHello3:

Проект Silverlight: SilverlightTapHello3 Файл: MainPage.xaml (фрагмент)

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <TextBlock Name="txtblk"

Text="Hello, Windows Phone 7!" Padding="0 34"

HorizontalAlignment="Center" VerticalAlignment="Center"

ManipulationStarted="OnTextBlockManipulationStarted" />

</Grid>

Имя (Name) TextBlock аналогично используемому в первой программе. В ней обработчик события ManipulationStarted задан для TextBlock. И обработчик события, и перегруженный OnManipulationStarted находятся в файле выделенного кода:

Проект Silverlight: SilverlightTapHello3 Файл: MainPage.xaml.cs (фрагмент)

public partial class MainPage : PhoneApplicationPage {

Random rand = new Random(); Brush originalBrush;

public MainPage() {

InitializeComponent(); originalBrush = txtblk.Foreground;

}

void OnTextBlockManipulationStarted(object sender,

ManipulationStartedEventArgs args)

{

txtblk.Foreground = new SolidColorBrush(

Color.FromArgb(255, (byte)rand.Next(25 6), (byte)rand.Next(256), (byte)rand.Next(256)));

args.Complete();

args.Handled = true;

}

protected override void OnManipulationStarted(ManipulationStartedEventArgs args) {

txtblk.Foreground = originalBrush; args.Complete();

base.OnManipulationStarted(args);

}

}

Логика разнесена на два метода, что делает всю обработку намного более элегантной, на мой взгляд. Метод OnTextBlockManipulationStarted принимает события, только когда происходит касание TextBlock. Событие OnManipulationStarted отвечает за все события MainPage.

На первый взгляд может показаться, что здесь ошибка. После вызова OnTextBlockManipulationStarted событие продолжает свое «путешествие» вверх по визуальному дереву, и OnManipulationStarted возвращает цвет к исходному белому. Но на самом деле происходит не это. Правильность выполнения всей логики обеспечивает выражение в конце обработчика OnTextBlockManipulationStarted для TextBlock:

args.Handled = true;

Это выражение говорит о том, что событие уже обработано и не должно передаваться далее вверх по визуальному дереву. Удалите это выражение – и TextBlock никогда не изменит своего исходного цвета, по крайней мере, не на так долго, чтобы это можно было заметить.

Странное поведение?

Теперь попробуем следующее. Во многих рассмотренных до сих пор приложениях на Silverlight центрирование TextBlock в рамках сетки для содержимого обеспечивалось следующими двумя атрибутами:

HorizontalAlignment="Center" VerticalAlignment="Center"

Удалите их из SilverlightTapHello3, выполните повторную компиляцию и запустите приложение. Текст будет выведен в верхнем левом углу Grid. Но теперь, если коснуться любой точки в области под TextBlock, текст будет менять свой цвет случайным образом. Возвращение к исходному белому цвету обеспечивается только касанием области заголовка над текстом.

По умолчанию свойствам HorizontalAlignment и VerticalAlignment присваивается значение Stretch. Фактически TextBlock заполняет весь Grid. Вы не можете видеть этого, но пальцы не лгут.

Как будет показано далее, для других элементов – отображающих растровые изображения, например – этот эффект растяжения намного более очевиден.

Источник: Чарльз Петзольд, Программируем Windows Phone 7, Microsoft Press, © 2011.

По теме:

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