Главная » Разработка для Windows Phone 7 » Содержимое и свойства содержимого Windows Phone 7

0

Всем известно, что XML может быть несколько «многословным», но тем не менее приведенный выше код разметки с градиентными кистями немного более «многословный», чем надо. Рассмотрим RadialGradientBrush, изначально заданный для TextBlock:

<TextBlock.Foreground>

<RadialGradientBrush>

<RadialGradientBrush.GradientStops> <GradientStopCollection>

<GradientStop Offset="0" Color="Transparent" /> <GradientStop Offset="1" Color="Red" /> </GradientStopCollection> </RadialGradientBrush.GradientStops> </RadialGradientBrush> </TextBlock.Foreground>

Во-первых, если в коллекции имеется хотя бы один элемент, теги самой коллекции можно убрать. Это означает, что теги GradientStopCollection могут быть опущены:

<TextBlock.Foreground>

<RadialGradientBrush>

<RadialGradientBrush.GradientStops>

<GradientStop Offset="0" Color="Transparent" /> <GradientStop Offset="1" Color="Red" /> </RadialGradientBrush.GradientStops> </RadialGradientBrush> </TextBlock.Foreground>

Более того, многие используемые в XAML классы имеют атрибут ContentProperty (Свойство содержимого). Слово «атрибут» имеет разное значение в .NET и XML. Здесь мы говорим о .NET-атрибуте, под которым подразумеваются некоторые дополнительные сведения, ассоциированные с классом или членом этого класса. Если взглянуть на документацию класса GradientBrush (класса, от которого наследуются и LinearGradientBrush, и RadialGradientBrush), можно увидеть, что в его описание включен атрибут типа ContentPropertyAttribute (Атрибут свойства содержимого):

[ContentPropertyAttribute("GradientStops", true)] public abstract class GradientBrush : Brush

Этот атрибут обозначает одно свойство этого класса, которое предполагается как содержимое этого класса, и для которого теги свойства-элемента не нужны. Для GradientBrush (и его потомков) таким свойством является GradientStops. Это означает, что теги RadialGradientBrush.GradientStops можно удалить из разметки:

<TextBlock.Foreground>

<RadialGradientBrush>

<GradientStop Offset="0" Color="Transparent" /> <GradientStop Offset="1" Color="Red" /> </RadialGradientBrush> </TextBlock.Foreground>

Теперь не так многословно, но при этом вполне понятно: два объекта GradientStop являются содержимым класса RadialGradientBrush.

Ранее в данной главе я создал TextBlock в коде и добавил его в коллекцию Children объекта Grid. Но в XAML мы не видим никакой ссылки на эту коллекцию Children. Ссылки нет, потому что атрибут ContentProperty класса Panel (родительского класса Grid) определяет свойство Children как содержимое Panel:

[ContentPropertyAttribute("Children", true)] public abstract class Panel : FrameworkElement

Чтобы сделать разметку более наглядной, в нее можно включить свойство-элемент для свойства Children:

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

<TextBlock Text="Hello, Windows Phone 7!" /> </Grid.Children> </Grid>

Аналогично PhoneApplicationPage наследуется от UserControl (Пользовательский элемент управления), у которого также есть атрибут ContentProperty

[ContentPropertyAttribute("Content", true)] public class UserControl : Control

Атрибут ContentProperty класса UserControl – это свойство Content. (Чтобы понять это предложение, его лучше увидеть, чем услышать!)

Предположим, требуется вставить в Grid два элемента TextBlock и в качестве Background для Grid использовать LinearGradientBrush. Для этого сначала в теги Grid можно поместить свойство-элемент Background и за ним добавить два элемента TextBlock:

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

<LinearGradientBrush>

<GradientStop Offset="0" Color="LightCyan" /> <GradientStop Offset="1" Color="LightPink" /> </LinearGradientBrush> </Grid.Background>

<TextBlock Text="TextBlock #1"

HorizontalAlignment="Left" />

<TextBlock Text="TextBlock #2"

HorizontalAlignment="Right" />

</Grid>

Также можно сначала задать два элемента TextBlock и после них вставить свойство-элемент Background:

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

HorizontalAlignment="Left" />

<TextBlock Text="TextBlock #2"

HorizontalAlignment="Right" />

<Grid.Background>

<LinearGradientBrush>

<GradientStop Offset="0" Color="LightCyan" /> <GradientStop Offset="1" Color="LightPink" /> </LinearGradientBrush> </Grid.Background> </Grid>

Но вот если поместить свойство-элемент Background между двумя TextBlock, ничего не получится:

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

HorizontalAlignment="Left" />

<!– Свойство-элемент не может располагаться здесь! –> <Grid.Background>

<LinearGradientBrush>

<GradientStop Offset="0" Color="LightCyan" /> <GradientStop Offset="1" Color="LightPink" />

</LinearGradientBrush> </Grid.Background>

<TextBlock Text="TextBlock #2"

HorizontalAlignment="Right" />

</Grid>

Абсолютно очевидные проблемы с этим синтаксисом выявляются, когда мы помещаем недостающие свойства-элементы для свойства Children нашего Grid:

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

<TextBlock Text="TextBlock #1"

HorizontalAlignment="Left" /> </Grid.Children>

<!– Свойство-элемент не может располагаться здесь! –> <Grid.Background>

<LinearGradientBrush>

<GradientStop Offset="0" Color="LightCyan" /> <GradientStop Offset="1" Color="LightPink" /> </LinearGradientBrush> </Grid.Background>

<Grid.Children>

<TextBlock Text="TextBlock #2"

HorizontalAlignment="Right" /> </Grid.Children> </Grid>

Теперь очевидно, что свойство Children задано дважды, и, несомненно, это неверно.

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

По теме:

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