TabbedPage

.NET MAUI TabbedPage.

.NET Multi-platform App UI (.NET MAUI) TabbedPage 会维护 Page 类型的子项集合,一次只有一个子项完全可见。 每个子项都由页面顶部或底部的一系列选项卡所标识。 通常来说,每个子项将是 ContentPage,当选中其选项卡时,将显示页面内容。

TabbedPage 定义以下属性:

  • BarBackground,类型为 Brush,定义选项卡栏的背景。
  • BarBackgroundColor,类型为 Color,定义选项卡栏的背景颜色。
  • BarTextColor,类型为 Color,表示选项卡栏上文本的颜色。
  • SelectedTabColor,类型为 Color,表示选项卡在被选中时的颜色。
  • UnselectedTabColor,类型为 Color,表示选项卡未被选中时的颜色。

这些属性由 BindableProperty 对象提供支持;也就是说,它们可以作为数据绑定的目标,并能进行样式设置。

选项卡的标题由子页面的 Page.Title 属性定义,选项卡图标由子页面的 Page.IconImageSource 属性定义。

TabbedPage 中,构造 Page 时,将创建每个 TabbedPage 对象。 这可能会导致用户体验不佳,在 TabbedPage 是应用的根页面的情况下更是如此。 但是,.NET MAUI Shell 允许按需创建通过选项卡栏访问的页面,以响应导航操作。 有关 Shell 应用的详细信息,请参阅 Shell

警告

TabbedPage 与 .NET MAUI Shell 应用不兼容,如果尝试在 Shell 应用中使用 TabbedPage,将引发异常。

创建 TabbedPage

可以使用两种方法创建 TabbedPage

重要

TabbedPage 应只能通过 NavigationPageContentPage 对象填充。

无论采用哪种方法,选项卡栏在 TabbedPage 中的位置都取决于平台:

  • 在 iOS 上,选项卡列表显示在屏幕底部,页面内容位于上方。 每个选项卡都由标题和图标组成。 在纵向方向,选项卡栏图标显示在选项卡标题上方。 在横向方向,图标和标题并排显示。 此外,可以根据设备和方向显示常规或精简选项卡栏。 如果有五个以上的选项卡,会显示“更多”选项卡,可用于访问其他选项卡
  • 在 Android 上,选项卡列表显示在屏幕顶部,页面内容位于下方。 每个选项卡都由标题和图标组成。 但是,可以使用特定于平台布局将选项卡移动至屏幕底部。 如果有五个以上的选项卡,并且选项卡列表位于屏幕底部,会显示“更多”选项卡,可用于访问其他选项卡。 有关将选项卡移动到屏幕底部的信息,请参阅 Android 上的 TabbedPage 工具栏放置
  • 在 Windows 上,选项卡列表显示在屏幕顶部,页面内容位于下方。 每个选项卡都包含一个标题。

使用页集合填充 TabbedPage

TabbedPage 可以通过子 Page 对象的集合填充,这些对象通常是 ContentPage 对象。 这是通过将 ContentPage 对象添加为 TabbedPage 的子项来实现的:

<TabbedPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:local="clr-namespace:TabbedPageWithNavigationPage"
            x:Class="TabbedPageWithNavigationPage.MainPage">
    <local:TodayPage />
    <local:SchedulePage />
    <local:SettingsPage />
</TabbedPage>

作为 TabbedPage 的子元素添加的 Page 对象将添加到 Children 集合中。 派生出 TabbedPageMultiPage<T> 类的 Children 属性是 MultiPage<T>ContentProperty。 因此,在 XAML 中,无需将 Page 对象显式分配给 Children 属性。

下面的屏幕截图显示了 TabbedPage 上生成的选项卡栏的外观:

.NET MAUI tab bar on a TabbedPage.

选择选项卡时,将显示选项卡的页面内容。

使用 DataTemplate 填充 TabbedPage

TabbedPageMultiPage<T> 类继承了 ItemsSourceItemTemplateSelectedItem 可绑定属性。 通过这些属性,可以将 ItemsSource 属性设置为具有适合数据绑定的公共属性的 IEnumerable 对象集合,并将 ItemTemplate 属性设置为将页面类型作为根元素的 DataTemplate,从而动态生成 TabbedPage 子项。

以下示例演示如何动态生成 TabbedPage 子项:

<TabbedPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:local="clr-namespace:TabbedPageDemo"
            x:Class="TabbedPageDemo.MainPage"
            ItemsSource="{x:Static local:MonkeyDataModel.All}">
    <TabbedPage.ItemTemplate>
        <DataTemplate>
            <ContentPage Title="{Binding Name}"
                         IconImageSource="monkeyicon.png">
                <StackLayout Padding="5, 25">
                    <Label Text="{Binding Name}"
                           FontAttributes="Bold"
                           FontSize="18"
                           HorizontalOptions="Center" />
                    <Image Source="{Binding PhotoUrl}"
                           HorizontalOptions="Center"
                           WidthRequest="200"
                           HeightRequest="200" />
                    <StackLayout Padding="50, 10">
                        <StackLayout Orientation="Horizontal">
                            <Label Text="Family: "
                                   FontAttributes="Bold" />
                            <Label Text="{Binding Family}" />
                        </StackLayout>
                        ...
                    </StackLayout>
                </StackLayout>
            </ContentPage>
        </DataTemplate>
    </TabbedPage.ItemTemplate>
</TabbedPage>

在此示例中,每个选项卡都包含一个 ContentPage 对象,该对象使用 ImageLabel 对象来显示该选项卡的数据:

Screenshot of a .NET MAUI TabbedPage.

导航可以在选项卡中执行,前提是 ContentPage 对象包装在 NavigationPage 对象中:

<TabbedPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:local="clr-namespace:TabbedPageWithNavigationPage"
            x:Class="TabbedPageWithNavigationPage.MainPage">
    <local:TodayPage />
    <NavigationPage Title="Schedule"
                    IconImageSource="schedule.png">
        <x:Arguments>
            <local:SchedulePage />
        </x:Arguments>
    </NavigationPage>
</TabbedPage>

在此示例中,使用两个 Page 对象填充 TabbedPage。 第一个子项是 ContentPage 对象,第二个子项是包含 ContentPage 对象的 NavigationPage 对象。

ContentPage 被包装在 NavigationPage 中时,可以通过调用 ContentPage 对象的 Navigation 属性上的 PushAsync 方法来执行向前页导航:

await Navigation.PushAsync(new UpcomingAppointmentsPage());

有关使用 NavigationPage 类执行导航的详细信息,请参阅 NavigationPage

警告

虽然 NavigationPage 可以放置在 TabbedPage 中,但不建议将 TabbedPage 放置到 NavigationPage 中。