如何在页面之间共享应用栏 (XAML)

Windows 运行时应用中的每个 Page 类都可以将 AppBar 控件分配给其 TopAppBarBottomAppBar 属性。但你可能希望在应用的相关页面之间使用同一 AppBar 来提供常见的导航或命令。例如,你可能会在你的应用的顶部提供一个导航栏,供用户在页面之间导航。 你希望为每个页面显示相同的导航栏,而不是在每个页面中重新创建它。

此处,我们演示了可在页面之间共享 AppBarCommandBar 的一些方法。此教程基于平面导航详细信息主题和相关的平面导航示例。请参阅平面导航示例以获取完整代码。

路线图: 本主题与其他主题有何关联?请参阅:

你需要了解的内容

技术

先决条件

说明

向页面添加共享应用栏

若要将某个常用应用栏添加到多个页面,请创建一个继承自 Page 类的新类。在本教程中,将创建一个名为 NavigationPage 的类。它从 Page 类继承了 TopAppBarBottomAppBar 属性。将导航命令添加顶部应用栏,而将其他共享命令添加到底部应用栏。然后,将应用页面更改为继承自 NavigationPage 而非 Page,这样每个页面便可以继承你所定义的命令。

JJ150604.wedge(zh-cn,WIN.10).gif添加共享的应用栏

  1. 创建一个派生自 Page 类的新类。在本教程中,将该类命名为 NavigationPage

    请参阅本教程末尾使用完整代码的 NavigationPage.cs。

    
    public class NavigationPage : Page
    {
        public NavigationPage()
        {
    
        }
    }
    
    
    
  2. 使用导航命令将一个 AppBar 控件分配给 NavigationPage 类的 TopAppBar 属性。AppBar 内容为下一步中所定义的 UserControl
    
    public class NavigationPage : Page
    {
        public NavigationPage()
        {
            Loaded += NavigationPage_Loaded;
        }
    
        void NavigationPage_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            // Navigation controls go in the top app bar.
            AppBar navBar = new AppBar();
            navBar.Background = new SolidColorBrush(new Color() { A=255, R = 0, G = 178, B = 240 }); 
            navBar.Content = new NavigationControl();
            this.TopAppBar = navBar;
        }
    }
    
    
    
  3. 因为 AppBar 控件可以包含任何内容,所以你可以将所有导航命令都放在 UserControl 中,并将 UserControl 设置为 AppBar 的内容。在本教程中,将 UserControl 命名为 NavigationControl
    
    <UserControl
        x:Class="FlatNavTemplate.NavigationControl"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:FlatNavTemplate"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300"
        d:DesignWidth="400">
        <UserControl.Resources>
            <Style TargetType="Button">
                <Setter Property="Width" Value="140"/>
                <Setter Property="Height" Value="60"/>
                <Setter Property="Margin" Value="5"/>
            </Style>
        </UserControl.Resources>
    
       <StackPanel Orientation="Horizontal">
            <Button x:Uid="appbarHome" Click="NavButton_Click" Tag="FlatNavTemplate.Pages.HomePage"/>
            <Button x:Uid="appbarPage2" Click="NavButton_Click" Tag="FlatNavTemplate.Pages.Page2"/>
            <!-- Add more buttons here as needed for new pages. -->
            <!-- Assign the fully qualified page name to the button's Tag property. -->
        </StackPanel>
    </UserControl>
    
    
  4. UserControl 的代码页面中 (NavigationControl.xaml.cs),添加代码以在页面之间导航。

    此处,你使用每个导航按钮的 Tag 属性指定要导航到的页面名称。

    
    public sealed partial class NavigationControl : UserControl
    {
        public NavigationControl()
        {
            this.InitializeComponent();
        }
    
        private void NavButton_Click(object sender, RoutedEventArgs e)
        {
            Button b = sender as Button;
            Frame rootFrame = Window.Current.Content as Frame;
    
            if (b != null && b.Tag != null)
            {
                Type pageType = Type.GetType(b.Tag.ToString());
    
                // Make sure the page type exists, but don't navigate to it if it's already the current page.
                if (pageType != null && rootFrame.CurrentSourcePageType != pageType)
                {
                    (App.Current as App).Navigate(pageType);
                }
                else if (pageType == null)
                {
                    // TODO: Optional - Do something if page not found.
                }
            }
        }
    }
    
    

向页面添加共享的 CommandBar

Windows 8.1:  CommandBarAppBarButton 控件仅在 Windows 8.1 和 Windows Phone 8.1 中可用。对于 Windows 8,使用 AppBarButton

JJ150604.wedge(zh-cn,WIN.10).gif添加共享的 CommandBar

  • CommandBar 添加到 NavigationPage 类的 BottomAppBar 属性。

    由于 CommandBar 只能有一个 AppBarButton 控件作为其内容,因此你不能采用与 AppBar 相同的方式将你的命令放置在 UserControl 中。但是,可在代码中添加命令。在本教程中,在 CommandBar 上添加了“帮助”按钮,以便可在所有页面之间进行共享。你可以在本教程末尾看到使用完整代码的“帮助”按钮的 Click 事件处理程序。有关详细信息,请参阅快速入门:添加应用帮助

    提示  

    你可以在用户导航到特定的页面时为该页面添加命令,并且在用户离开该页面时删除这些命令。有关详细信息,请参阅如何将上下文命令添加到应用栏

    
    public class NavigationPage : Page
    {
        public NavigationPage()
        {
            Loaded += NavigationPage_Loaded;
        }
    
        void NavigationPage_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            // CommandBar for Help command goes in the BottomAppBar.
            CommandBar commandBar = new CommandBar();
            commandBar.Background = new SolidColorBrush(new Color() { A = 255, R = 0, G = 178, B = 240 });
                
            // Create the Help button.
            AppBarButton helpButton = new AppBarButton();
            helpButton.Icon = new SymbolIcon(Symbol.Help);
            helpButton.Label = "Help";
            helpButton.Click += helpButton_Click;
                
            // Add the Help button to the command bar.
            commandBar.PrimaryCommands.Add(helpButton);
            this.BottomAppBar = commandBar;
        }
    }
    
    
    

将页面添加到应用

  1. 添加用户可以在其间导航的应用页面。

    请参阅本教程末尾的使用完整的代码的 HomePage.xaml 和 Page2.xaml。

  2. 将应用页面更改为继承自 NavigationPage 而非 Page。每个继承自 NavigationPage 的页面都具有定义的导航和帮助命令。

    以下是已更新为继承自 NavigationPageHomePage 的定义。

    
    
    <nav:NavigationPage
        x:Name="pageRoot"
        x:Class="FlatNavTemplate.Pages.HomePage"
        DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:nav="using:FlatNavTemplate"
        xmlns:local="using:FlatNavTemplate.Pages"
        xmlns:common="using:FlatNavTemplate.Common"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <-- PAGE CONTENT -->   
        </Grid>
    </nav:NavigationPage>
    
    
    
    
    public sealed partial class HomePage : NavigationPage
    {
    
    }
    
    

备注

下载平面导航示例以在操作中查看此代码。

完整示例

NavigationPage


using Windows.UI;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

namespace FlatNavTemplate
{
    public class NavigationPage : Page
    {
        public static NavigationPage Current;

        public NavigationPage()
        {
            Loaded += NavigationPage_Loaded;
        }

        void NavigationPage_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            // To access the app bars from the code of a derived page, 
            // use NavigationPage.Current.TopAppBar or NavigationPage.Current.BottomAppBar.
            Current = this;

            // Navigation controls go in the top app bar.
            AppBar navBar = new AppBar();
            navBar.Background = new SolidColorBrush(new Color() { A=255, R = 0, G = 178, B = 240 });
            navBar.Content = new NavigationControl();
            this.TopAppBar = navBar;

            // CommandBar for Help command goes in the BottomAppBar.
            CommandBar commandBar = new CommandBar();
            commandBar.Background = new SolidColorBrush(new Color() { A = 255, R = 0, G = 178, B = 240 });
            // Create the Help button.
            AppBarButton helpButton = new AppBarButton();
            helpButton.Icon = new SymbolIcon(Symbol.Help);
            helpButton.Label = "Help";
            helpButton.Click += helpButton_Click;
            // Add the Help button to the command bar.
            commandBar.PrimaryCommands.Add(helpButton);
            this.BottomAppBar = commandBar;
        }

        void helpButton_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            Settings.HelpSettings helpSettingsFlyout = new Settings.HelpSettings();
            // When the settings flyout is opened from the app bar instead of from
            // the Settings charm, use the ShowIndependent() method.
            helpSettingsFlyout.ShowIndependent();

            // Close the app bars.
            this.TopAppBar.IsOpen = false;
            this.BottomAppBar.IsOpen = false;
        }
    }
}

NavigationControl


<UserControl
    x:Class="FlatNavTemplate.NavigationControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:FlatNavTemplate"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400">
    <UserControl.Resources>
        <Style TargetType="Button">
            <Setter Property="Width" Value="140"/>
            <Setter Property="Height" Value="60"/>
            <Setter Property="Margin" Value="5"/>
        </Style>
    </UserControl.Resources>
    
    <StackPanel Orientation="Horizontal">       
        <Button x:Uid="appbarHome" Click="NavButton_Click" Tag="FlatNavTemplate.Pages.HomePage"/>
        <Button x:Uid="appbarPage2" Click="NavButton_Click" Tag="FlatNavTemplate.Pages.Page2"/>
        <!-- Add more buttons here as needed for new pages. -->
        <!-- Assign the fully qualified page name to the button's Tag property. -->
    </StackPanel>
</UserControl>



namespace FlatNavTemplate
{
    public sealed partial class NavigationControl : UserControl
    {
        public NavigationControl()
        {
            this.InitializeComponent();
        }

        private void NavButton_Click(object sender, RoutedEventArgs e)
        {
            Button b = sender as Button;
            Frame rootFrame = Window.Current.Content as Frame;

            if (b != null && b.Tag != null)
            {
                Type pageType = Type.GetType(b.Tag.ToString());

                // Make sure the page type exists, but don't navigate to it if it's already the current page.
                if (pageType != null && rootFrame.CurrentSourcePageType != pageType)
                {
                    (App.Current as App).Navigate(pageType);
                }
                else if (pageType == null)
                {
                    // TODO: Optional - Do something if page not found.
                }
            }
        }
    }
}

HomePage


<nav:NavigationPage
    x:Name="pageRoot"
    x:Class="FlatNavTemplate.Pages.HomePage"
    DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:nav="using:FlatNavTemplate"
    xmlns:local="using:FlatNavTemplate.Pages"
    xmlns:common="using:FlatNavTemplate.Common"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Page.Resources>
        <!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
        <x:String x:Key="AppName">My Application</x:String>
    </Page.Resources>

    <!--
        This grid acts as a root panel for the page that defines two rows:
        * Row 0 contains the back button and page title
        * Row 1 contains the rest of the page layout
    -->
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ChildrenTransitions>
            <TransitionCollection>
                <EntranceThemeTransition/>
            </TransitionCollection>
        </Grid.ChildrenTransitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="140"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- Back button and page title -->
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="120"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Image x:Name="logoimage" HorizontalAlignment="Center" Height="100" VerticalAlignment="Center" 
                   Width="100" Source="ms-appx:///Assets/square70logo.png" IsHitTestVisible="False"/>
            <TextBlock x:Name="pageTitle" Text="{StaticResource AppName}" 
                       Style="{StaticResource HeaderTextBlockStyle}" Grid.Column="1" 
                       IsHitTestVisible="false" TextWrapping="NoWrap" VerticalAlignment="Bottom" 
                       Margin="0,0,30,40"/>
        </Grid>
    </Grid>
</nav:NavigationPage>


public sealed partial class HomePage : NavigationPage
{
    // Only class definition is shown. Template code is removed for clarity.
}

Page2


<nav:NavigationPage
    x:Name="pageRoot"
    x:Class="FlatNavTemplate.Pages.Page2"
    DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:nav="using:FlatNavTemplate"
    xmlns:local="using:FlatNavTemplate.Pages"
    xmlns:common="using:FlatNavTemplate.Common"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Page.Resources>
        <!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
        <x:String x:Key="AppName">My Application Page 2</x:String>
    </Page.Resources>
    
    <!--
        This grid acts as a root panel for the page that defines two rows:
        * Row 0 contains the back button and page title
        * Row 1 contains the rest of the page layout
    -->
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ChildrenTransitions>
            <TransitionCollection>
                <EntranceThemeTransition/>
            </TransitionCollection>
        </Grid.ChildrenTransitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="140"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- Back button and page title -->
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="120"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Image x:Name="logoimage" HorizontalAlignment="Center" Height="100" VerticalAlignment="Center" 
                   Width="100" Source="ms-appx:///Assets/square70logo.png" IsHitTestVisible="False"/>
            <TextBlock x:Name="pageTitle" Text="{StaticResource AppName}" 
                       Style="{StaticResource HeaderTextBlockStyle}" Grid.Column="1" 
                        IsHitTestVisible="false" TextWrapping="NoWrap" 
                       VerticalAlignment="Bottom" Margin="0,0,30,40"/>
        </Grid>
    </Grid>
</nav:NavigationPage>


public sealed partial class Page2 : NavigationPage
{
    // Only class definition is shown. Template code is removed for clarity.
}

相关主题

平面导航示例
XAML 应用栏控件示例
快速入门:添加应用栏
快速入门:在页面之间导航
平面导航详细信息 (XAML)
Windows 应用商店应用的导航设计
Windows 应用商店应用的命令设计

 

 

显示:
© 2015 Microsoft