StackLayout
.NET Multi-platform App UI (.NET MAUI) StackLayout 以水平或垂直方式在一维堆栈中组织子视图。 默认情况下,StackLayout 是垂直方向。 此外,还可以将 StackLayout 用作包含其他子布局的父布局。
StackLayout 类定义以下属性:
Orientation
,类型为StackOrientation
,表示子视图的放置方向。 此属性的默认值为Vertical
。Spacing
,类型为double
,指示每个子视图之间的间距。 此属性的默认值为 0。
所有这些属性都由 BindableProperty 对象提供支持,这意味着这些属性可以作为数据绑定的目标并设置样式。
垂直方向
以下 XAML 展示了如何创建包含不同子视图的垂直方向的 StackLayout:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="StackLayoutDemos.Views.XAML.VerticalStackLayoutPage"
Title="Vertical StackLayout demo">
<StackLayout Margin="20">
<Label Text="Primary colors" />
<BoxView Color="Red"
HeightRequest="40" />
<BoxView Color="Yellow"
HeightRequest="40" />
<BoxView Color="Blue"
HeightRequest="40" />
<Label Text="Secondary colors" />
<BoxView Color="Green"
HeightRequest="40" />
<BoxView Color="Orange"
HeightRequest="40" />
<BoxView Color="Purple"
HeightRequest="40" />
</StackLayout>
</ContentPage>
本示例会创建包含 Label 和 BoxView 对象的垂直 StackLayout。 默认情况下,子视图之间没有空白:
等效 C# 代码如下:
public class VerticalStackLayoutPage : ContentPage
{
public VerticalStackLayoutPage()
{
Title = "Vertical StackLayout demo";
StackLayout stackLayout = new StackLayout { Margin = new Thickness(20) };
stackLayout.Add(new Label { Text = "Primary colors" });
stackLayout.Add(new BoxView { Color = Colors.Red, HeightRequest = 40 });
stackLayout.Add(new BoxView { Color = Colors.Yellow, HeightRequest = 40 });
stackLayout.Add(new BoxView { Color = Colors.Blue, HeightRequest = 40 });
stackLayout.Add(new Label { Text = "Secondary colors" });
stackLayout.Add(new BoxView { Color = Colors.Green, HeightRequest = 40 });
stackLayout.Add(new BoxView { Color = Colors.Orange, HeightRequest = 40 });
stackLayout.Add(new BoxView { Color = Colors.Purple, HeightRequest = 40 });
Content = stackLayout;
}
}
注意
Margin
属性的值表示元素与其相邻元素之间的距离。 有关详细信息,请参阅位置控件。
水平方向
以下 XAML 展示了如何通过将水平的 StackLayout 的 Orientation
属性设置为 Horizontal
来创建它:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="StackLayoutDemos.Views.XAML.HorizontalStackLayoutPage"
Title="Horizontal StackLayout demo">
<StackLayout Margin="20"
Orientation="Horizontal"
HorizontalOptions="Center">
<BoxView Color="Red"
WidthRequest="40" />
<BoxView Color="Yellow"
WidthRequest="40" />
<BoxView Color="Blue"
WidthRequest="40" />
<BoxView Color="Green"
WidthRequest="40" />
<BoxView Color="Orange"
WidthRequest="40" />
<BoxView Color="Purple"
WidthRequest="40" />
</StackLayout>
</ContentPage>
此示例会创建包含 BoxView 对象的水平 StackLayout,子视图之间没有空白:
等效 C# 代码如下:
public class HorizontalStackLayoutPage : ContentPage
{
public HorizontalStackLayoutPage()
{
Title = "Horizontal StackLayout demo";
StackLayout stackLayout = new StackLayout
{
Margin = new Thickness(20),
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.Center
};
stackLayout.Add(new BoxView { Color = Colors.Red, WidthRequest = 40 });
stackLayout.Add(new BoxView { Color = Colors.Yellow, WidthRequest = 40 });
stackLayout.Add(new BoxView { Color = Colors.Blue, WidthRequest = 40 });
stackLayout.Add(new BoxView { Color = Colors.Green, WidthRequest = 40 });
stackLayout.Add(new BoxView { Color = Colors.Orange, WidthRequest = 40 });
stackLayout.Add(new BoxView { Color = Colors.Purple, WidthRequest = 40 });
Content = stackLayout;
}
}
子视图之间的间距
可以通过将 Spacing
属性设置为 double
值来更改 StackLayout 中子视图之间的间距:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="StackLayoutDemos.Views.XAML.StackLayoutSpacingPage"
Title="StackLayout Spacing demo">
<StackLayout Margin="20"
Spacing="6">
<Label Text="Primary colors" />
<BoxView Color="Red"
HeightRequest="40" />
<BoxView Color="Yellow"
HeightRequest="40" />
<BoxView Color="Blue"
HeightRequest="40" />
<Label Text="Secondary colors" />
<BoxView Color="Green"
HeightRequest="40" />
<BoxView Color="Orange"
HeightRequest="40" />
<BoxView Color="Purple"
HeightRequest="40" />
</StackLayout>
</ContentPage>
此示例会创建包含 Label 和 BoxView 对象的垂直 StackLayout,这些对象之间有六个与设备无关的垂直空白单位:
提示
可以将 Spacing
属性设置为负值,以使子视图重叠。
等效 C# 代码如下:
public class StackLayoutSpacingPage : ContentPage
{
public StackLayoutSpacingPage()
{
Title = "StackLayout Spacing demo";
StackLayout stackLayout = new StackLayout
{
Margin = new Thickness(20),
Spacing = 6
};
stackLayout.Add(new Label { Text = "Primary colors" });
stackLayout.Add(new BoxView { Color = Colors.Red, HeightRequest = 40 });
stackLayout.Add(new BoxView { Color = Colors.Yellow, HeightRequest = 40 });
stackLayout.Add(new BoxView { Color = Colors.Blue, HeightRequest = 40 });
stackLayout.Add(new Label { Text = "Secondary colors" });
stackLayout.Add(new BoxView { Color = Colors.Green, HeightRequest = 40 });
stackLayout.Add(new BoxView { Color = Colors.Orange, HeightRequest = 40 });
stackLayout.Add(new BoxView { Color = Colors.Purple, HeightRequest = 40 });
Content = stackLayout;
}
}
子视图的位置和大小
StackLayout 中子视图的大小和位置取决于子视图的 HeightRequest 和 WidthRequest 属性的值,以及其 HorizontalOptions
和 VerticalOptions
属性的值。 在垂直 StackLayout 中,子视图会在未显式设置其大小时展开,以填充可用宽度。 同样,在水平 StackLayout 中,子视图会在未显式设置其大小时展开,以填充可用高度。
可以将 StackLayout 的 HorizontalOptions
和 VerticalOptions
属性及其子视图设置为 LayoutOptions
结构中的字段,该结构封装了对齐方式布局首选项。 此布局首选项可确定子视图在其父布局中的位置和大小。
以下 XAML 示例会设置每个子视图在 StackLayout 中的对齐方式首选项:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="StackLayoutDemos.Views.XAML.AlignmentPage"
Title="Alignment demo">
<StackLayout Margin="20"
Spacing="6">
<Label Text="Start"
BackgroundColor="Gray"
HorizontalOptions="Start" />
<Label Text="Center"
BackgroundColor="Gray"
HorizontalOptions="Center" />
<Label Text="End"
BackgroundColor="Gray"
HorizontalOptions="End" />
<Label Text="Fill"
BackgroundColor="Gray"
HorizontalOptions="Fill" />
</StackLayout>
</ContentPage>
在此示例中,在 Label 对象上设置了对齐方式首选项,以控制它们在 StackLayout 中的位置。 Start
、Center
、End
和 Fill
字段用于定义父级 StackLayout 中 Label 对象的对齐方式:
StackLayout 仅遵循与 StackLayout 方向相反的子视图的对齐方式首选项。 因此,垂直方向的 StackLayout 中的 Label 子视图将其 HorizontalOptions
属性设置为对齐方式字段中的其中一种:
Start
,它将 Label 置于 StackLayout 的左侧。Center
,它将 Label 置于 StackLayout 中心。End
,它将 Label 置于 StackLayout 的右侧。Fill
,确保 Label 填充到 StackLayout 的宽度。
等效 C# 代码如下:
public class AlignmentPage : ContentPage
{
public AlignmentPage()
{
Title = "Alignment demo";
StackLayout stackLayout = new StackLayout
{
Margin = new Thickness(20),
Spacing = 6
};
stackLayout.Add(new Label { Text = "Start", BackgroundColor = Colors.Gray, HorizontalOptions = LayoutOptions.Start });
stackLayout.Add(new Label { Text = "Center", BackgroundColor = Colors.Gray, HorizontalOptions = LayoutOptions.Center });
stackLayout.Add(new Label { Text = "End", BackgroundColor = Colors.Gray, HorizontalOptions = LayoutOptions.End });
stackLayout.Add(new Label { Text = "Fill", BackgroundColor = Colors.Gray, HorizontalOptions = LayoutOptions.Fill });
Content = stackLayout;
}
}
有关对齐方式的详细信息,请参阅在布局中对齐视图。
嵌套的 StackLayout 对象
StackLayout 可用作包含嵌套子 StackLayout 对象或其他子布局的父布局。
以下 XAML 展示了一个嵌套 StackLayout 对象的示例:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="StackLayoutDemos.Views.XAML.CombinedStackLayoutPage"
Title="Combined StackLayouts demo">
<StackLayout Margin="20">
...
<Frame BorderColor="Black"
Padding="5">
<StackLayout Orientation="Horizontal"
Spacing="15">
<BoxView Color="Red"
WidthRequest="40" />
<Label Text="Red"
FontSize="18"
VerticalOptions="Center" />
</StackLayout>
</Frame>
<Frame BorderColor="Black"
Padding="5">
<StackLayout Orientation="Horizontal"
Spacing="15">
<BoxView Color="Yellow"
WidthRequest="40" />
<Label Text="Yellow"
FontSize="18"
VerticalOptions="Center" />
</StackLayout>
</Frame>
<Frame BorderColor="Black"
Padding="5">
<StackLayout Orientation="Horizontal"
Spacing="15">
<BoxView Color="Blue"
WidthRequest="40" />
<Label Text="Blue"
FontSize="18"
VerticalOptions="Center" />
</StackLayout>
</Frame>
...
</StackLayout>
</ContentPage>
在此示例中,父级 StackLayout 在 Frame 对象中包含嵌套的 StackLayout 对象。 父级 StackLayout 对象是垂直放置的,而子级 StackLayout 对象是水平放置的:
重要
将 StackLayout 对象和其他布局嵌套得越深,执行的布局计算就越多,这可能会影响性能。 有关详细信息,请参阅选择正确的布局。
等效 C# 代码如下:
public class CombinedStackLayoutPage : ContentPage
{
public CombinedStackLayoutPage()
{
Title = "Combined StackLayouts demo";
Frame frame1 = new Frame
{
BorderColor = Colors.Black,
Padding = new Thickness(5)
};
StackLayout frame1StackLayout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
Spacing = 15
};
frame1StackLayout.Add(new BoxView { Color = Colors.Red, WidthRequest = 40 });
frame1StackLayout.Add(new Label { Text = "Red", FontSize = 22, VerticalOptions = LayoutOptions.Center });
frame1.Content = frame1StackLayout;
Frame frame2 = new Frame
{
BorderColor = Colors.Black,
Padding = new Thickness(5)
};
StackLayout frame2StackLayout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
Spacing = 15
};
frame2StackLayout.Add(new BoxView { Color = Colors.Yellow, WidthRequest = 40 });
frame2StackLayout.Add(new Label { Text = "Yellow", FontSize = 22, VerticalOptions = LayoutOptions.Center });
frame2.Content = frame2StackLayout;
Frame frame3 = new Frame
{
BorderColor = Colors.Black,
Padding = new Thickness(5)
};
StackLayout frame3StackLayout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
Spacing = 15
};
frame3StackLayout.Add(new BoxView { Color = Colors.Blue, WidthRequest = 40 });
frame3StackLayout.Add(new Label { Text = "Blue", FontSize = 22, VerticalOptions = LayoutOptions.Center });
frame3.Content = frame3StackLayout;
...
StackLayout stackLayout = new StackLayout { Margin = new Thickness(20) };
stackLayout.Add(new Label { Text = "Primary colors" });
stackLayout.Add(frame1);
stackLayout.Add(frame2);
stackLayout.Add(frame3);
stackLayout.Add(new Label { Text = "Secondary colors" });
stackLayout.Add(frame4);
stackLayout.Add(frame5);
stackLayout.Add(frame6);
Content = stackLayout;
}
}