如何使用大小不同的应用栏

Applies to Windows only

默认情况下,应用栏按钮的宽度为 100 设备无关像素 (DIP),并且在其图标下方有文本标签。如果用户缩小应用大小,则水平空间不足,无法显示命令。如果应用栏中的按钮过多,你必须进行一些调整,以使按钮正确显示在较小的宽度中。

注意  如果在 CommandBar 控件中托管应用栏内容,则 CommandBar 会处理其子应用栏按钮控件的布局和大小调整。仅当在 AppBar 控件中托管应用栏内容时,才需要用到此教程中的技术。

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

你需要了解的内容

技术

先决条件

说明

步骤 1: 隐藏标签并减少宽度 (Windows 8.1)

Windows 8.1:  此步骤仅适用于 Windows 8.1。对于 Windows 8,请参阅步骤 3。

这些示例中的代码使用以 Extensible Application Markup Language (XAML) 定义的 AppBar


<Page.BottomAppBar>
    <AppBar x:Name="bottomAppBar" IsSticky="True">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            
            <StackPanel x:Name="leftAppBarPanel" Orientation="Horizontal">
                <AppBarButton Label="Save" Icon="Save"/>
                <AppBarButton Label="Discard" Icon="Delete"/>
                <AppBarButton Label="Edit" Icon="Edit"/>
                <AppBarButton Label="Undo" Icon="Undo"/>
                <AppBarButton Label="Redo" Icon="Redo"/>
            </StackPanel>
            
            <StackPanel x:Name="rightAppBarPanel" 
                        Orientation="Horizontal" HorizontalAlignment="Right">
                <AppBarButton Label="Skip Back" Icon="Previous"/>
                <AppBarButton Label="Skip Ahead" Icon="Next"/>
                <AppBarButton Label="Play" Icon="Play"/>
                <AppBarButton Label="Pause" Icon="Pause"/>
                <AppBarButton Label="Stop" Icon="Stop"/>
            </StackPanel>
        </Grid>
    </AppBar>
</Page.BottomAppBar>

在 1024 像素宽的应用中,此应用栏如下所示。

含有 10 个按钮的应用栏

当应用的宽度为 320 像素时,该应用栏在默认情况下将如下所示。

在辅屏视图中含有 10 个按钮的应用栏

这些应用栏按钮控件(AppBarButtonAppBarToggleButton)包含两种大小:正常和精简。默认情况下,按钮包含一个文本标签并进行完全填充。当 IsCompact 属性设置为 true 时,文本标签会被隐藏,按钮周围的填充也会相应减少。AppBarSeparator 也提供精简状态,在精简状态下填充空间会相应减少。若要使应用栏按钮使用较少的空间,请将 IsCompact 属性设置为 true

如果 CommandBar 中未托管应用栏按钮,则必须使用代码管理其 IsCompact 属性。 为此,你侦听页面的 SizeChanged 事件,然后针对新的窗口大小相应设置每个应用栏按钮的 IsCompact 属性。

JJ662742.wedge(zh-cn,WIN.10).gif调整按钮大小

  1. 注册页面的 SizeChanged 事件。
    
    public MainPage()
    {
        this.InitializeComponent();
    
        // Register for the SizeChanged event.
        this.SizeChanged += MainPage_SizeChanged;
    }
    
    
    
  2. SizeChanged 事件处理程序中,检查页面宽度是否已更改。如果更改,则更新 AppBar 的布局。
    
    void MainPage_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        if (e.NewSize.Width != e.PreviousSize.Width)
        {
            UpdateBottomAppBarLayout(e.NewSize.Width);
        }
    }
    
    
  3. 若要更新 AppBar 布局,请根据页面宽度设置每个按钮的 IsCompact 属性。在本示例中,有 10 个 AppBarButton,每个的宽度为 100 DIP,因此如果页面宽度小于 1000,则需要精简按钮。
    
    private void UpdateAppBarButtons(double newWidth)
    {
        if (newWidth < 1000)
        {
            ToggleIsCompact(true);
        }
        else
        {
            ToggleIsCompact(false);
        }
    }
    
    

    如果具有固定数量的按钮,则可以使用代码或 VisualStateManager 在每个上面分别设置 IsCompact 属性。或者,可以循环设置,如下所示。此代码假设应用栏使用布局和根 Panel(包含托管按钮的其他 Panel)。

    
    private void ToggleIsCompact(bool isCompact)
    {
        // Get the app bar's root Panel.
        Panel root = bottomAppBar.Content as Panel;
        if (root != null)
        {
            // Get the Panels that hold the controls.
            foreach (Panel panel in root.Children)
            {
                foreach (ICommandBarElement child in panel.Children)
                {
                    child.IsCompact = isCompact;
                }
            }
        }
    }
    
    

现在,当用户缩小应用大小时,会重新调整按钮大小,并且应用栏如下所示。

窄应用中的应用栏

步骤 2: 重新调整按钮大小和隐藏按钮 (Windows 8.1)

Windows 8.1:  此步骤仅适用于 Windows 8.1。对于 Windows 8,请参阅步骤 4。

注意  在此步骤中,我们假设应用栏按钮处于上一步中介绍的精简状态,没有任何文本标签,且已减少宽度。
在应用栏最窄的情况下,它的宽度仅足以在一行中显示 5 个AppBarButton。如果你的应用栏中有 5 个以上按钮,你必须将这些按钮排列为 2 行,隐藏一些按钮,或者同事执行这两项。

JJ662742.wedge(zh-cn,WIN.10).gif将按钮移动到 2 行的步骤

  1. 若要将按钮重新排列为 2 行,请为应用栏使用如下布局。使用带有 2 行和 2 个面板(通常是 StackPanel)的根 Grid 容纳这些按钮。
    
    <AppBar>
        <Grid>
            <Grid.RowDefinitions>
               <RowDefinition Height="Auto"/>
               <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
                    
            <StackPanel x:Name="leftAppBarPanel" Orientation="Horizontal">
                <!-- Buttons -- >
            </StackPanel>
                    
            <StackPanel x:Name="rightAppBarPanel" Orientation="Horizontal" 
                        HorizontalAlignment="Right">
                <!-- Buttons -- >
            </StackPanel>
        </Grid>
    </AppBar>
    
    
  2. 当应用太窄,无法在一行中显示所有的按钮时,请将 rightAppBarPanel 元素的 Grid.Row 属性值改为 1,将面板的 HorizontalAlignment 属性改为 Left

    当你需要保证主要(右)和次要(左)按钮都可见时,此操作很有用。如果不需要保证次要命令可见,则可以按照以下所示隐藏这些命令。

    当应用处于最窄状态时,右侧的按钮将移动到底部的一行。应用栏如下所示。

    辅屏视图中带有 2 行的应用栏

    在此示例中,有 10 个 AppBarButton,当其处于精简状态时每个的宽度为 60 DIP。如果页面宽度小于 600,你需要精简按钮并通过移动分为 2 行。

    
    private void UpdateBottomAppBarLayout(double newWidth)
    {
        if (newWidth < 600)
        {
            ToggleIsCompact(true);
            rightAppBarPanel.SetValue(Grid.RowProperty, 1);
            rightAppBarPanel.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Left);
        }
        else if (newWidth < 1000)
        {
            ToggleIsCompact(true);
            rightAppBarPanel.SetValue(Grid.RowProperty, 0);
            rightAppBarPanel.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Right);
        }
        else
        {
            ToggleIsCompact(false);
            rightAppBarPanel.SetValue(Grid.RowProperty, 0);
            rightAppBarPanel.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Right);
        }
    }
    
    

JJ662742.wedge(zh-cn,WIN.10).gif隐藏按钮的步骤

  • 当应用太窄,无法在一行中显示所有的按钮时,请将 leftAppBarPanel 元素的 Visibility 属性值改为 Collapsed

    当应用处于最窄状态时,左面板中的按钮将被隐藏。应用栏如下所示。

    辅屏视图中带有 1 行的应用栏

    在此示例中,有 10 个 AppBarButton,当其处于精简状态时每个的宽度为 60 DIP。如果页面宽度小于 600,你需要精简按钮并隐藏次要命令。

    
    private void UpdateBottomAppBarLayout(double newWidth)
    {
        if (newWidth < 600)
        {
            ToggleIsCompact(true);
            leftAppBarPanel.SetValue(VisibilityProperty, Visibility.Collapsed);
    
        }
        else if (newWidth < 1000)
        {
            ToggleIsCompact(true);
            leftAppBarPanel.SetValue(VisibilityProperty, Visibility.Visible);
        }
        else
        {
            ToggleIsCompact(false);
            leftAppBarPanel.SetValue(VisibilityProperty, Visibility.Visible);
        }
    }
    
    

步骤 3: 隐藏标签并减少宽度 (Windows 8)

Windows 8:  此步骤仅适用于 Windows 8。对于 Windows 8.1,请参阅步骤 1。在 Windows 8.1 中,AppBarButtonStyle 被弃用并使用 AppBarButton 控件替代。

这些示例中的代码使用以 XAML 定义的 AppBar

注意  若要使用此处所示的 "AppBarButtonStyle" 资源,你必须编辑 StandardStyles.xaml 文件才能使用这些资源。有关详细信息,请参阅快速入门:添加应用栏按钮

<Page.BottomAppBar>
    <AppBar x:Name="bottomAppBar" IsSticky="True" 
            Loaded="appBar_Loaded" Unloaded="appBar_Unloaded">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            
            <StackPanel x:Name="leftAppBarPanel" Orientation="Horizontal">
                <Button Style="{StaticResource SaveAppBarButtonStyle}"/>
                <Button Style="{StaticResource DiscardAppBarButtonStyle}"/>
                <Button Style="{StaticResource EditAppBarButtonStyle}"/>
                <Button Style="{StaticResource UndoAppBarButtonStyle}"/>
                <Button Style="{StaticResource RedoAppBarButtonStyle}"/>
            </StackPanel>
            
            <StackPanel x:Name="rightAppBarPanel" 
                        Orientation="Horizontal" HorizontalAlignment="Right">
                <Button Style="{StaticResource SkipBackAppBarButtonStyle}"/>
                <Button Style="{StaticResource SkipAheadAppBarButtonStyle}"/>
                <Button Style="{StaticResource PlayAppBarButtonStyle}"/>
                <Button Style="{StaticResource PauseAppBarButtonStyle}"/>
                <Button Style="{StaticResource StopAppBarButtonStyle}"/>
            </StackPanel>
        </Grid>
    </AppBar>
</Page.BottomAppBar>

在 1024 像素宽的应用中,此应用栏如下所示。

含有 10 个按钮的应用栏

当应用贴靠时,该应用栏在默认情况下将如下所示。

在辅屏视图中含有 10 个按钮的应用栏

为了使应用栏按钮占用较少的空间,AppBarButtonStyle 基本 Style 包含了在 SnappedFullScreenPortrait 视图中隐藏按钮标签并减少其宽度的 VisualStateVisualStateAppBarButtonStyle 资源中进行定义,但默认情况下,控件不知道应用的视图状态。为了让应用栏按钮根据应用的视图状态更改状态,你必须提供其他代码以使 Button 知道应用视图状态已发生更改。 你提供的代码取决于承载应用栏的页面是否派生自 LayoutAwarePage 类。

注意  Microsoft Visual Studio 非空白页以外的页面模板派生自 LayoutAwarePage 类。LayoutAwarePage 是对 Page 的实现,它支持 Windows 应用商店应用开发的重要功能(如视图状态管理、基本导航和应用会话状态管理)。有关详细信息,请参阅 C#、VB 和 C++ 项模板

LayoutAwarePage 中,任何控件都可以调用 StartLayoutUpdates 以注册接收对应于应用视图状态更改的视觉状态更改。这意味着当应用视图状态更改为 Snapped 时,应用栏按钮可以转到其 Snapped 视图状态。

JJ662742.wedge(zh-cn,WIN.10).gif在 LayoutAwarePage 中调整按钮大小的步骤

  1. 如果 AppBar 只有 1 或 2 个命令,你可以在其 LoadedUnloaded 事件中单独注册和注销命令,如下所示。
    
    <Button Style="{StaticResource PlayAppBarButtonStyle}"
            Loaded="StartLayoutUpdates" Unloaded="StopLayoutUpdates"/>
    
    
  2. 如果应用栏有多个按钮,则最好在加载和卸载应用栏时,在代码中注册和注销全部按钮,如下所示。

    此代码假设应用栏使用带有根 Panel(其中包含承载按钮的其他 Panel)的布局。每个按钮都在加载 AppBar 时注册接收状态更改,并在卸载应用栏时注销。

    LoadedUnloaded 事件都在如前所示的 AppBar XAML 中进行注册。

    
    
    private void appBar_Loaded(object sender, RoutedEventArgs e)
    {
        // Get the app bar's root Panel.
        Panel root = ((AppBar)sender).Content as Panel;
        if (root != null)
        {
            // Get the Panels that hold the controls.
            foreach (Panel panel in root.Children)
            {
                // Get each control and register for layout updates.
                foreach (UIElement child in panel.Children)
                {
                    base.StartLayoutUpdates(child, new RoutedEventArgs());
                }
            }
        }
    }
    
    private void appBar_Unloaded(object sender, RoutedEventArgs e)
    {
        // Get the app bar's root Panel.
        Panel root = ((AppBar)sender).Content as Panel;
        if (root != null)
        {
            // Get the Panels that hold the controls.
            foreach (Panel panel in root.Children)
            {
                // Get each control and unregister layout updates.
                foreach (UIElement child in panel.Children)
                {
                    base.StopLayoutUpdates(child, new RoutedEventArgs());
                }
            }
        }
    }
    
    

如果承载应用栏的页面未派生自 LayoutAwarePage,你必须在页面中提供功能以更改 Button 的视图状态。为此,你需要侦听应用视图状态更改,然后在应用的视图状态更改时为每个应用栏按钮调用 ViewStateManager.GoToState

JJ662742.wedge(zh-cn,WIN.10).gif在空白页中调整按钮大小的步骤

  1. 注册窗口的 SizeChanged 事件。
    
    public MainPage()
    {
        this.InitializeComponent();
    
        // Register for the SizeChanged event.
        Window.Current.SizeChanged += Current_SizeChanged;
    }
    
    
    
  2. SizeChanged 事件处理程序中,检查应用栏是否已打开。如果是,更新每个按钮的视图状态。

    以下代码处理应用视图状态在应用栏处于打开状态时发生更改的情况。

    
    void Current_SizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
    {
        if (bottomAppBar.IsOpen == true)
        {
            UpdateAppBarButtonsViewState();
        }
    }
    
    
  3. AppBarLoaded 事件添加一个处理程序。在 Loaded 事件处理程序中,更新每个按钮的视图状态。

    以下代码处理在应用视图状态发生更改后打开应用栏的情况。

    Loaded 事件是在如前所示的 AppBar XAML 中注册的。

    
    private void bottomAppBar_Loaded(object sender, RoutedEventArgs e)
    {
        UpdateAppBarButtonsViewState();
    }
    
    
  4. 若要更新每个按钮的视图状态,请调用 VisualStateManager.GoToState 并传入应用的当前视图状态。

    如果你的应用栏只有 1 或 2 个命令,你可以单独指定并对命令调用 GoToState,如下所示。

    
    private void UpdateAppBarButtonsViewState()
    {
        string viewState = Windows.UI.ViewManagement.ApplicationView.Value.ToString();
    
        VisualStateManager.GoToState(playButton, viewState, true);
        VisualStateManager.GoToState(stopButton, viewState, true);
    }
    
    

    如果应用栏有多个按钮,则最好循环操作这些按钮,如下所示。此代码假设应用栏使用带有根 Panel(其中包含承载按钮的其他 Panel)的布局。

    
    private void UpdateAppBarButtonViewState()
    {
        string viewState = Windows.UI.ViewManagement.ApplicationView.Value.ToString();
    
        // Get the app bar's root Panel.
        Panel root = bottomAppBar.Content as Panel;
        if (root != null)
        {
            // Get the Panels that hold the controls.
            foreach (Panel panel in root.Children)
            {
                // Get each control and update its state if 
               // it's a Button or ToggleButton.
                foreach (UIElement child in panel.Children)
                {
                    if (child.GetType() == typeof(Button) || 
                        child.GetType() == typeof(ToggleButton))
                    {
                        VisualStateManager.GoToState((ButtonBase)child, viewState, true);
                    }
                }
            }
        }
    }
    
    

现在,当应用旋转到纵向并且按钮调整大小时,应用栏将如下所示。

纵向视图的应用栏

步骤 4: 重新排列和隐藏按钮 (Windows 8)

Windows 8:  此步骤仅适用于 Windows 8。对于 Windows 8.1,请参阅步骤 2。在 Windows 8.1 中,AppBarButtonStyle 被弃用并使用 AppBarButton 控件替代。

注意  在此步骤中,我们假设应用栏按钮处于上一步中介绍的 Snapped VisualState,没有任何文本标签,且已减少宽度。
Snapped 视图中,应用栏的宽度仅足以在一行中显示 5 个按钮。如果你的应用栏中有 5 个以上按钮,你必须将这些按钮排列为 2 行,隐藏一些按钮,或者同事执行这两项。

JJ662742.wedge(zh-cn,WIN.10).gif将按钮移动到 2 行的步骤

  1. 若要将按钮重新排列为 2 行,请为应用栏使用如下布局。使用带有 2 行和 2 个面板(通常是 StackPanel)的根 Grid 容纳这些按钮。
    
    <AppBar>
        <Grid>
            <Grid.RowDefinitions>
               <RowDefinition Height="Auto"/>
               <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
                    
            <StackPanel x:Name="leftAppBarPanel" Orientation="Horizontal">
                <!-- Buttons -- >
            </StackPanel>
                    
            <StackPanel x:Name="rightAppBarPanel" Orientation="Horizontal" HorizontalAlignment="Right">
                <!-- Buttons -- >
            </StackPanel>
        </Grid>
    </AppBar>
    
    
  2. Snapped VisualState 下,将 rightAppBarPanel 元素的 Grid.Row 属性值更改为 1 并将面板的 HorizontalAlignment 属性更改为 Left

    当应用贴靠时,右侧的按钮将移动到底部的一行。应用栏如下所示。

    辅屏视图中带有 2 行的应用栏

    
    <VisualStateManager.VisualStateGroups>
        ...
            <VisualState x:Name="Snapped">
                <Storyboard>
                    ... 
    
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="rightAppBarPanel" 
                                                   Storyboard.TargetProperty="(Grid.Row)">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="1"/>
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="rightAppBarPanel" 
                                           Storyboard.TargetProperty="HorizontalAlignment">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="Left"/>
                    </ObjectAnimationUsingKeyFrames>
                    ...
                </Storyboard>
            </VisualState>
        ...
    </VisualStateManager.VisualStateGroups>
    
    

JJ662742.wedge(zh-cn,WIN.10).gif隐藏按钮的步骤

  • Snapped VisualState 下,将 leftAppBarPanelVisibility 属性值更改为 Collapsed

    当应用贴靠时,左面板中的按钮将被隐藏。应用栏如下所示。

    辅屏视图中带有 1 行的应用栏

    
    <VisualStateManager.VisualStateGroups>
        ...
            <VisualState x:Name="Snapped">
                <Storyboard>
                    ...
    
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="leftAppBarPanel" 
                                                   Storyboard.TargetProperty="Visibility">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </VisualState>
        ...
    </VisualStateManager.VisualStateGroups>
    
    

备注

你可以通过隐藏整个面板(如上所示),或者以相同的方式隐藏单个按钮,在 Snapped 视图中隐藏不太重要的命令。若要隐藏单个按钮,你必须指定其名称,以便在 VisualStateManager 中引用。

 

 

显示:
© 2015 Microsoft