<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.GridDemoPage"
Title="Grid Demo Page">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Label Text="Autosized cell"
Grid.Row="0" Grid.Column="0"
TextColor="White"
BackgroundColor="Blue" />
<BoxView Color="Silver"
HeightRequest="0"
Grid.Row="0" Grid.Column="1" />
<BoxView Color="Teal"
Grid.Row="1" Grid.Column="0" />
<Label Text="Leftover space"
Grid.Row="1" Grid.Column="1"
TextColor="Purple"
BackgroundColor="Aqua"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center" />
<Label Text="Span two rows (or more if you want)"
Grid.Row="0" Grid.Column="2" Grid.RowSpan="2"
TextColor="Yellow"
BackgroundColor="Blue"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center" />
<Label Text="Span two columns"
Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2"
TextColor="Blue"
BackgroundColor="Yellow"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center" />
<Label Text="Fixed 100x100"
Grid.Row="2" Grid.Column="2"
TextColor="Aqua"
BackgroundColor="Red"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center" />
</Grid>
</ContentPage>
Grid.Row
不需要 0 和Grid.Column
设置,但通常包含在明确性方面。
如下所示:
从语法来看,这些、属性和属性似乎是静态字段或属性Grid
,但有趣的是,Grid
没有定义任何命名Row
、Column
、或RowSpan
ColumnSpan
。Grid.ColumnSpan
Grid.RowSpan
Grid.Column
Grid.Row
Grid
而是定义四个可绑定属性,名为 RowProperty
,ColumnProperty
RowSpanProperty
和ColumnSpanProperty
。 这些是称为 附加属性的特殊类型的可绑定属性。 它们由 Grid
类定义,但设置在子 Grid
级上。
如果要在代码中使用这些附加属性,类Grid
会提供命名SetRow
GetColumn
的静态方法,等等。 但在 XAML 中,这些附加属性在使用简单属性名称的 Grid
子级中设置为属性。
附加属性在 XAML 文件中始终可识别为包含类和由句点分隔的属性名称的属性。 它们称为 附加属性 ,因为它们在本例中由一个类 (定义, Grid
) 但附加到此示例中的其他对象 (,即) 的 Grid
子级。 在布局期间, Grid
可以询问这些附加属性的值,以了解放置每个子项的位置。
该 AbsoluteLayout
类定义两个名为 LayoutBounds
和 LayoutFlags
. 的附加属性。 下面是使用比例定位和大小调整功能 AbsoluteLayout
实现的棋板模式:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.AbsoluteDemoPage"
Title="Absolute Demo Page">
<AbsoluteLayout BackgroundColor="#FF8080">
<BoxView Color="#8080FF"
AbsoluteLayout.LayoutBounds="0.33, 0, 0.25, 0.25"
AbsoluteLayout.LayoutFlags="All" />
<BoxView Color="#8080FF"
AbsoluteLayout.LayoutBounds="1, 0, 0.25, 0.25"
AbsoluteLayout.LayoutFlags="All" />
<BoxView Color="#8080FF"
AbsoluteLayout.LayoutBounds="0, 0.33, 0.25, 0.25"
AbsoluteLayout.LayoutFlags="All" />
<BoxView Color="#8080FF"
AbsoluteLayout.LayoutBounds="0.67, 0.33, 0.25, 0.25"
AbsoluteLayout.LayoutFlags="All" />
<BoxView Color="#8080FF"
AbsoluteLayout.LayoutBounds="0.33, 0.67, 0.25, 0.25"
AbsoluteLayout.LayoutFlags="All" />
<BoxView Color="#8080FF"
AbsoluteLayout.LayoutBounds="1, 0.67, 0.25, 0.25"
AbsoluteLayout.LayoutFlags="All" />
<BoxView Color="#8080FF"
AbsoluteLayout.LayoutBounds="0, 1, 0.25, 0.25"
AbsoluteLayout.LayoutFlags="All" />
<BoxView Color="#8080FF"
AbsoluteLayout.LayoutBounds="0.67, 1, 0.25, 0.25"
AbsoluteLayout.LayoutFlags="All" />
</AbsoluteLayout>
</ContentPage>
如下所示:
对于这样的事情,你可能会质疑使用 XAML 的智慧。 当然,矩形的 LayoutBounds
重复和规律性表明,它可能会在代码中更好地实现。
这当然是一个合法的问题,在定义用户界面时平衡代码和标记的使用没有问题。 在 XAML 中定义某些视觉对象很容易,然后使用代码隐藏文件的构造函数添加一些可能更好地在循环中生成的视觉对象。
在前面的示例中,对象StackLayout
Grid
和AbsoluteLayout
对象设置为Content
属性ContentPage
,这些布局的子级实际上是集合中的Children
项。 然而,这些 Content
属性和 Children
属性在 XAML 文件中没有位置。
当然,可以包括Content
Children
属性元素和属性,例如在 XamlPlusCode 示例中:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.XamlPlusCodePage"
Title="XAML + Code Page">
<ContentPage.Content>
<StackLayout>
<StackLayout.Children>
<Slider VerticalOptions="CenterAndExpand"
ValueChanged="OnSliderValueChanged" />
<Label x:Name="valueLabel"
Text="A simple Label"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Button Text="Click Me!"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Clicked="OnButtonClicked" />
</StackLayout.Children>
</StackLayout>
</ContentPage.Content>
</ContentPage>
真正的问题是:为什么 XAML 文件中 不需要 这些属性元素?
允许在 Xamarin.Forms XAML 中使用的元素在类的属性 ContentProperty
中标记一个属性。 如果在联机Xamarin.Forms文档中查找ContentPage
该类,你将看到此属性:
[Xamarin.Forms.ContentProperty("Content")]
public class ContentPage : TemplatedPage
这意味着 Content
不需要属性元素标记。 假定在开始标记和结束 ContentPage
标记之间显示的任何 XML 内容都分配给该 Content
属性。
StackLayout
、Grid
、AbsoluteLayout
和RelativeLayout
所有派生自Layout<View>
,如果在文档中查找Layout<T>
Xamarin.Forms,你将看到另一个ContentProperty
属性:
[Xamarin.Forms.ContentProperty("Children")]
public abstract class Layout<T> : Layout ...
这允许将布局的内容自动添加到集合中 Children
,而无需显式 Children
属性元素标记。
其他类还具有 ContentProperty
属性定义。 例如,内容属性为 Label
Text
. 查看其他 API 文档。
在单页应用程序中,通常设置 Padding
页面上的属性以避免覆盖 iOS 状态栏。 在代码中,可以使用此属性 Device.RuntimePlatform
实现此目的:
if (Device.RuntimePlatform == Device.iOS)
Padding = new Thickness(0, 20, 0, 0);
还可以使用 OnPlatform
和 On
类在 XAML 中执行类似操作。 首先包括页面顶部附近属性的属性元素 Padding
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
</ContentPage.Padding>
</ContentPage>
在这些标记中,包括标记 OnPlatform
。 OnPlatform
是泛型类。 在这种情况下,需要指定泛型类型参数, Thickness
即属性的类型 Padding
。 幸运的是,有一个 XAML 属性专门定义调用 x:TypeArguments
的泛型参数。 这应与要设置的属性的类型匹配:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
</OnPlatform>
</ContentPage.Padding>
</ContentPage>
OnPlatform
具有一 Platforms
IList
On
个名为对象的属性。 对该属性使用属性元素标记:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<OnPlatform.Platforms>
</OnPlatform.Platforms>
</OnPlatform>
</ContentPage.Padding>
</ContentPage>
现在添加 On
元素。 对于每个属性,将 Platform
属性和 Value
属性设置为 Thickness
标记属性:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<OnPlatform.Platforms>
<On Platform="iOS" Value="0, 20, 0, 0" />
<On Platform="Android" Value="0, 0, 0, 0" />
<On Platform="UWP" Value="0, 0, 0, 0" />
</OnPlatform.Platforms>
</OnPlatform>
</ContentPage.Padding>
</ContentPage>
可以简化此标记。 的内容属性 OnPlatform
, Platforms
因此可以删除这些属性元素标记:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS" Value="0, 20, 0, 0" />
<On Platform="Android" Value="0, 0, 0, 0" />
<On Platform="UWP" Value="0, 0, 0, 0" />
</OnPlatform>
</ContentPage.Padding>
</ContentPage>
On
属性Platform
的类型IList<string>
,因此,如果值相同,则可以包含多个平台:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS" Value="0, 20, 0, 0" />
<On Platform="Android, UWP" Value="0, 0, 0, 0" />
</OnPlatform>
</ContentPage.Padding>
</ContentPage>
由于 Android 和 UWP 设置为默认值 Padding
,因此可以删除该标记:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS" Value="0, 20, 0, 0" />
</OnPlatform>
</ContentPage.Padding>
</ContentPage>
这是在 XAML 中设置依赖于 Padding
平台的属性的标准方法。 Value
如果设置不能由单个字符串表示,则可以为其定义属性元素:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="...">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS">
<On.Value>
0, 20, 0, 0
</On.Value>
</OnPlatform>
</ContentPage.Padding>
</ContentPage>
还可以 OnPlatform
在 XAML 中使用标记扩展来自定义每个平台的 UI 外观。 它提供的功能与OnPlatform
On
类相同,但具有更简洁的表示形式。 有关详细信息,请参阅 OnPlatform 标记扩展。
使用属性元素和附加属性,已建立大部分基本 XAML 语法。 但是,有时需要以间接方式将属性设置为对象,例如,从资源字典中设置属性。 下一部分第 3 部分介绍了此方法 。XAML 标记扩展。
XamlSamples
第 1 部分。 XAML 入门
第 3 部分。 XAML 标记扩展
第 4 部分。 数据绑定基础知识
第 5 部分。 从数据绑定到 MVVM