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

0

XAML не является настоящим языком программирования. Он не включает ничего похожего на выражения if. XAML не может принимать решения.

Но это не означает, что мы не будем пытаться это сделать.

Как можно было заметить, класс Clock использовал обычное свойство Hour класса DateTime, значением которого является показание времени в 24-часовом формате. Что делать, если мы хотим использовать 12-часовой формат и выводить рядом с показаниями времени текст «AM» или «PM» для обозначения первой или второй половины суток.

Обычно это делается путем форматирования времени (если класс Clock действительно предоставил объект DateTime, отражающий время). Однако предположим, мы хотим иметь большую гибкость в отображении данных AM и PM – возможно, выводить текст «утра» или «вечера» – и мы хотим делать это в XAML.

Рассмотрим новый класс TwelveHourClock (Время в 12-часовом формате), который наследуется от Clock.

Проект Silverlight: Petzold.Phone.Silverlight Файл: TwelveHourClock.cs

using System;

using System.ComponentModel;

namespace Petzold.Phone.Silverlight {

public class TwelveHourClock : Clock {

int hour12;

bool isam, ispm;

public int Hour12 {

protected set {

if (value != hour12) {

hour12 = value;

0nPropertyChanged(new PropertyChangedEventArgs("Hour12"));

}

}

get {

return hour12;

}

}

public bool IsAm {

protected set {

if (value != isam) {

isam = value;

0nPropertyChanged(new PropertyChangedEventArgs("IsAm"));

}

}

get {

return isam;

}

}

public bool IsPm {

protected set {

if (value != ispm) {

ispm = value;

0nPropertyChanged(new PropertyChangedEventArgs("IsPm"));

}

}

get {

return ispm;

}

}

protected override void 0nPropertyChanged(PropertyChangedEventArgs args) {

if (args.PropertyName == "Hour") {

Hour12 = (Hour – 1) % 12 + 1; IsAm = Hour < 12; IsPm = !IsAm;

}

base.0nPropertyChanged(args);

}

}

}

Класс TwelveHourClock описывает три свойства: Hour12 и два свойства типа Boolean, IsAm и IsPm. Каждое из них формирует событие PropertyChanged. Перегруженный метод OnPropertyChanged проверяет, является измененное свойство свойством Hour. Если да, он

вычисляет новые значения для всех трех свойств, что само по себе опять приводит к вызову OnPropertyChanged.

isAm является просто логическим отрицанием isPM. Отсюда возникает справедливый вопрос, чем обусловлена необходимость в наличии двух свойств. Это объясняется просто: XAML не может самостоятельно выполнить операцию логического отрицания, поэтому и нужны два свойства.

Создадим экземпляр класса TwelveHourClock в коллекции Resources и присвоим ему ключ «clock12»:

<phone:PhoneApplicationPage.Resources>

<petzold:TwelveHourClock x:Key="clock12" /> </phone:PhoneApplicationPage.Resources>

Чтобы с помощью XAML вывести на экран примерно такой текст: «It’s after 9 in the morning[17]» – мы сделали бы следующее:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <StackPanel DataContext="{StaticResource clock12}" 0rientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> <TextBlock Text="It’s after " /> <TextBlock Text="{Binding Hour}" /> <TextBlock Text=" in the morning." /> <TextBlock Text=" in the afternoon." /> </StackPanel> </Grid>

В данном XAML предлагаются две отдельные строки для утра и дня, но на экран должна выводиться только одна из них в зависимости от того, какое из свойств, IsAm или IsPm, имеет значение true. Как вообще это можно реализовать?

Необходим еще один конвертер. Его имя BooleanToVisibilityConverter (Конвертер логического значения в значение видимости), и он будет использоваться довольно часто. Данный конвертер предполагает, что значение источника типа Boolean, а целевой объект – свойство типа Visibility:

Проект Silverlight: Petzold.Phone.Silverlight Файл: BooleanToVisibilityConverter.cs

using System;

using System.Globalization; using System.Windows; using System.Windows.Data;

namespace Petzold.Phone.Silverlight {

public class BooleanToVisibilityConverter : IValueConverter {

public object Convert(object value, Type targetType,

object parameter, CultureInfo culture)

{

return (bool)value ? Visibility.Visible : Visibility.Collapsed;

}

public object ConvertBack(object value, Type targetType,

object parameter, CultureInfo culture)

{

return (Visibility)value == Visibility.Visible;

}

Добавим этот класс в коллекцию Resources:

<phone:PhoneApplicationPage.Resources>

<petzold:TwelveHourClock x:Key="clock12" />

<petzold:BooleanToVisibilityConverter x:Key="booleanToVisibility" /> </phone:PhoneApplicationPage.Resources>

Теперь используя BooleanToVisibilityConverter, свяжем посредством привязки свойства Visibility последних двух элементов TextBlock со свойствами IsAm и IsPm. Рассмотрим разметку из проекта AmOrPm:

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

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <StackPanel DataContext="{StaticResource clock12}" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> <TextBlock Text="It’s after " /> <TextBlock Text="{Binding Hour}" /> <TextBlock Text=" in the morning."

Visibility="{Binding IsAm,

Converter={StaticResource booleanToVisibility}}"

/>

<TextBlock Text=" in the afternoon."

Visibility="{Binding IsPm,

Converter={StaticResource

booleanToVisibility}}"/>

</StackPanel> </Grid>

И это работает:

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

По теме:

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