问题描述
我正在尝试构建一个如下所示的 CommandBar:
I am trying to build a CommandBar that looks like this:
带有带有图标的 SecondaryCommands 的所需 CommandBar
Desired CommandBar with SecondaryCommands that have icons
但我找不到一种方法来编辑 CommandOverflowPresenter 的默认样式,以便像 Mail Windows 10 通用应用程序中显示的那样显示 SecondaryCommands,左侧带有图标,右侧带有文本标签.
But I can't find a way to edit the default style of CommandOverflowPresenter in order to show SecondaryCommands like they are shown in Mail Windows 10 universal app, with icons on the left and text labels on the right.
CommandOverflowPresenter 没有 Content 属性来围绕它构建控件模板并将内容元素绑定到 AppBarButton Icon 和 Label 属性.
The CommandOverflowPresenter doesn't have a Content property to build a control template around it and bind content elements to AppBarButton Icon and Label properties.
我发现了这篇文章,但它没有显示样式AppBarButton.
I found this article, but it doesn't show the Style for the AppBarButton.
Stack Overflow 上还有一个问题,结论是构建自定义的 CommandOverflowPresenter 样式.你是怎么做到的?
There was another question on Stack Overflow, and the conclusion is to build a custom CommandOverflowPresenter style. How do you do that?
默认 CommandOverflowPresenter 样式:
Default CommandOverflowPresenter style:
<!-- Default style for Windows.UI.Xaml.Controls.CommandBarOverflowPresenter -->
<Style TargetType="CommandBarOverflowPresenter">
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundChromeMediumLowBrush}" />
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundChromeHighBrush}" />
<Setter Property="MaxWidth" Value="{ThemeResource CommandBarOverflowMaxWidth}"/>
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.ZoomMode" Value="Disabled" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CommandBarOverflowPresenter">
<Grid x:Name="LayoutRoot" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,1" >
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="DisplayModeStates">
<VisualState x:Name="DisplayModeDefault" />
<VisualState x:Name="FullWidthOpenDown" >
<VisualState.Setters>
<Setter Target="LayoutRoot.BorderThickness" Value="0,0,0,1" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="FullWidthOpenUp" >
<VisualState.Setters>
<Setter Target="LayoutRoot.BorderThickness" Value="0,1,0,0" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ScrollViewer
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}"
AutomationProperties.AccessibilityView="Raw">
<ItemsPresenter x:Name="ItemsPresenter" Margin="0,7,0,7"/>
</ScrollViewer>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这是我试过的.
CommandOverflowPresenter 是一个 ItemsControl,我在 CommandOverflowPresenter 样式中为其 ItemTemplate 添加了一个 Setter,并让 Content 模板保持默认样式.
CommandOverflowPresenter is an ItemsControl and I added a Setter for its ItemTemplate in CommandOverflowPresenter style, and let the Content template as it was in the default style.
运行时,次要命令按照默认样式显示,只显示文本标签,不显示图标.
When running, the secondary commands are displayed according to the default style, only text labels are displayed, but not the icons.
也许在 ItemTemplate 的 DataTemplate 中没有正确设置绑定?
Perhaps the bindings are not set up properly in the ItemTemplate's DataTemplate?
<CommandBar.CommandBarOverflowPresenterStyle>
<Style TargetType="CommandBarOverflowPresenter">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CommandBarOverflowPresenter">
<Grid x:Name="LayoutRoot" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,1" >
<!--<Grid.Resources>
<DataTemplate x:Key="SecondaryMenu">
<StackPanel Orientation="Horizontal">
<SymbolIcon Symbol="{TemplateBinding AppBarButton.Icon}"/>
<TextBlock Text="{TemplateBinding AppBarButton.Label}" />
</StackPanel>
</DataTemplate>
</Grid.Resources>-->
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="DisplayModeStates">
<VisualState x:Name="DisplayModeDefault" />
<VisualState x:Name="FullWidthOpenDown" >
<VisualState.Setters>
<Setter Target="LayoutRoot.BorderThickness" Value="0,0,0,1" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="FullWidthOpenUp" >
<VisualState.Setters>
<Setter Target="LayoutRoot.BorderThickness" Value="0,1,0,0" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ScrollViewer
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}"
AutomationProperties.AccessibilityView="Raw">
<ItemsPresenter x:Name="ItemsPresenter" Margin="0,7,0,7">
</ItemsPresenter>
</ScrollViewer>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate x:DataType="AppBarButton">
<StackPanel Orientation="Horizontal">
<SymbolIcon Symbol="{Binding Icon}" />
<TextBlock Text="{Binding Label}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</CommandBar.CommandBarOverflowPresenterStyle>
我还尝试在 AppBarButton 标签内添加一个 StackPanel,其中包含一个 SymbolIcon 和一个 Textblock,但这也不起作用.
I also tried to add a StackPanel inside the AppBarButton tags with a SymbolIcon and a Textblock, but that didn't work either.
推荐答案
我们可以编辑AppBarButton
的默认样式和模板来实现这一点.而且我认为没有必要构建自定义的 CommandOverflowPresenter
样式.
We can edit the default style and template of AppBarButton
to achieve this. And I think there is no need to build a custom CommandOverflowPresenter
style.
Microsoft 为默认模板提供了 XAML 代码,我们可以在 AppBarButton 样式和模板.我们可以将此样式复制到 Page.Resources
并为该样式指定一个键,例如 x:Key="MyAppBarButtonStyle"
.
Microsoft has provided XAML code for the default template, we can find at AppBarButton styles and templates. We can copy this style to Page.Resources
and give this style a key like x:Key="MyAppBarButtonStyle"
.
默认情况下,图标和文本垂直放置在ContentRoot"StackPanel
中.我们可以像下面这样改变它,将它们水平放置.
By default, the icon and text are placed vertically in the "ContentRoot" StackPanel
. We can change it like following to put them Horizontally.
<StackPanel x:Name="ContentRoot" MinHeight="{ThemeResource AppBarThemeCompactHeight}" Orientation="Horizontal">
<ContentPresenter x:Name="Content"
Margin="12,0,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
Content="{TemplateBinding Icon}"
Foreground="{TemplateBinding Foreground}" />
<TextBlock x:Name="TextLabel"
Margin="12,0,12,0"
VerticalAlignment="Center"
FontFamily="{TemplateBinding FontFamily}"
FontSize="15"
Foreground="{TemplateBinding Foreground}"
Text="{TemplateBinding Label}"
TextAlignment="Center"
TextWrapping="Wrap" />
</StackPanel>
此后,我们需要像您提到的文章一样更改溢出"VisualState
,以确保图标可以显示在二级菜单中.
After this, we need to change the "Overflow" VisualState
like the article you mentioned to make sure the icon can be shown in secondary menu.
<VisualState x:Name="Overflow">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OverflowTextLabel" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
除此之外,我们可能还需要更改 AppBarButton
的 HorizontalAlignment
和 Width
属性,如下所示,以便 StackPanel
可以使用 CommandOverflowPresenter
的全宽.
Besides these, we may also need to change the HorizontalAlignment
and Width
property of AppBarButton
like following so that the StackPanel
can take full width of CommandOverflowPresenter
.
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Width" Value="Auto" />
最后,我们可以在 SecondaryCommands
中使用这种样式.
Finally, we can use this style in SecondaryCommands
.
<CommandBar.SecondaryCommands>
<AppBarButton Style="{StaticResource MyAppBarButtonStyle}"
Click="AppBarButton_Click"
Icon="Like"
Label="Like" />
<AppBarButton Style="{StaticResource MyAppBarButtonStyle}"
Click="AppBarButton_Click"
Icon="Dislike"
Label="Dislike" />
</CommandBar.SecondaryCommands>
完整的样式可能如下:
<Style x:Key="MyAppBarButtonStyle" TargetType="AppBarButton">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Width" Value="Auto" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="AppBarButton">
<Grid x:Name="Root"
MinWidth="{TemplateBinding MinWidth}"
MaxWidth="{TemplateBinding MaxWidth}"
Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ApplicationViewStates">
<VisualState x:Name="FullSize" />
<VisualState x:Name="Compact">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Overflow">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OverflowTextLabel" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="OverflowWithToggleButtons">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OverflowTextLabel" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OverflowTextLabel" Storyboard.TargetProperty="Margin">
<DiscreteObjectKeyFrame KeyTime="0" Value="38,0,12,0" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<Storyboard>
<PointerUpThemeAnimation Storyboard.TargetName="OverflowTextLabel" />
</Storyboard>
</VisualState>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightListLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OverflowTextLabel" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<PointerUpThemeAnimation Storyboard.TargetName="OverflowTextLabel" />
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Root" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightListMediumBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OverflowTextLabel" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
</ObjectAnimationUsingKeyFrames>
<PointerDownThemeAnimation Storyboard.TargetName="OverflowTextLabel" />
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OverflowTextLabel" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="InputModeStates">
<VisualState x:Name="InputModeDefault" />
<VisualState x:Name="TouchInputMode">
<VisualState.Setters>
<Setter Target="OverflowTextLabel.Padding" Value="0,11,0,13" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<StackPanel x:Name="ContentRoot" MinHeight="{ThemeResource AppBarThemeCompactHeight}" Orientation="Horizontal">
<ContentPresenter x:Name="Content"
Margin="12,0,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
Content="{TemplateBinding Icon}"
Foreground="{TemplateBinding Foreground}" />
<TextBlock x:Name="TextLabel"
Margin="12,0,12,0"
VerticalAlignment="Center"
FontFamily="{TemplateBinding FontFamily}"
FontSize="15"
Foreground="{TemplateBinding Foreground}"
Text="{TemplateBinding Label}"
TextAlignment="Center"
TextWrapping="Wrap" />
</StackPanel>
<TextBlock x:Name="OverflowTextLabel"
Margin="12,0,12,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
FontFamily="{TemplateBinding FontFamily}"
FontSize="15"
Foreground="{TemplateBinding Foreground}"
Padding="0,5,0,7"
Text="{TemplateBinding Label}"
TextAlignment="Left"
TextTrimming="Clip"
TextWrapping="NoWrap"
Visibility="Collapsed" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这篇关于如何将图标添加到命令栏中的 SecondaryCommands的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!