在 CommandBar 的 SecondaryCommand 上设置图标

Set Icon on SecondaryCommand of CommandBar

我有一个命令栏宽度辅助命令:

<CommandBar>
    <AppBarButton Icon="Back" Label="Back" Click="AppBarButton_Click"/>
    <AppBarButton Icon="Stop" Label="Stop" Click="AppBarButton_Click"/>
    <AppBarButton Icon="Play" Label="Play" Click="AppBarButton_Click"/>
    <AppBarButton Icon="Forward" Label="Forward" Click="AppBarButton_Click"/>

    <CommandBar.SecondaryCommands>
        <AppBarButton Icon="Like" Label="Like" Click="AppBarButton_Click"/>
        <AppBarButton Icon="Dislike" Label="Dislike" Click="AppBarButton_Click"/>
    </CommandBar.SecondaryCommands>
</CommandBar>

为什么不显示“喜欢”和“不喜欢”图标?

在 Windows 8.1 中,主要和次要命令是一种将按钮放在左侧和右侧的方法。在 Windows 10 UWP 中,辅助命令被移动到桌面和 phone 上的弹出菜单中。此弹出菜单中默认不显示图标。

The SecondaryCommands collection can contain only AppBarButton, AppBarToggleButton, or AppBarSeparator command elements. The secondary commands are shown in the overflow menu when the CommandBar is open.

来源:MSDN.

如果您想尝试覆盖样式,请查看 generic.xaml 中的 OverflowPopup 控件和 CommandBarOverflowPresenter 样式以开始使用。

C:\Program Files (x86)\Windows Kits\DesignTime\CommonConfiguration\Neutral\UAP.0.10240.0\Generic\generic.xaml

我想到了另一种方法。希望这会有所帮助。

想法是利用 AppBarToggleButton.

Checked 状态

创建另一个扩展 AppBarToggleButton.

的 class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;

namespace <YOUR_NAMESPACE>
{
    sealed class SecondaryIconButton : AppBarToggleButton
    {
        public static readonly DependencyProperty GlyphProperty = DependencyProperty.Register(
            "Glyph", typeof( string ), typeof( SecondaryIconButton )
            , new PropertyMetadata( SegoeMDL2.Accept, OnGlyphChanged ) );

        public string Glyph
        {
            get { return ( string ) GetValue( GlyphProperty ); }
            set { SetValue( GlyphProperty, value ); }
        }

        private TextBlock GlyphText;

        public SecondaryIconButton( string Glyph )
            :base()
        {
            IsChecked = true;
            this.Glyph = Glyph;
        }

        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            GlyphText = ( TextBlock ) GetTemplateChild( "OverflowCheckGlyph" );
            GlyphText.Width = GlyphText.Height = 16;

            UpdateGlyph();
        }

        // Force the button to always be checked
        protected override void OnPointerReleased( PointerRoutedEventArgs e )
        {
            base.OnPointerReleased( e );
            IsChecked = true;
        }

        private void UpdateGlyph()
        {
            if ( GlyphText == null ) return;
            GlyphText.Text = Glyph;
        }

        private static void OnGlyphChanged( DependencyObject d, DependencyPropertyChangedEventArgs e )
        {
            ( ( SecondaryIconButton ) d ).UpdateGlyph();
        }
    }
}

请注意 SegeoMDL2.Accept 也是一个自定义 class 派生自:
https://msdn.microsoft.com/windows/uwp/style/segoe-ui-symbol-font

现在您可以在 xaml 中调用它:

<ns:SecondaryIconButton Glyph="&#xE73E;" />

或者在后面的代码中创建它:

new SecondaryIconButton( Glyph ) { Label = Label };

参考:
SecondaryIconButton.cs
SegoeMDL2.cs

完整代码有效

public sealed class SecondaryIconButton : AppBarToggleButton
{
    public SecondaryIconButton()
    {
        this.Loaded += SecondaryIconButton_Loaded;
    }

    private void SecondaryIconButton_Loaded(object sender, RoutedEventArgs e)
    {
        UpdateGlyph();
        IsChecked = true;
    }

    public static readonly DependencyProperty GlyphProperty = DependencyProperty.Register(
        "Glyph", typeof(string), typeof(SecondaryIconButton)
        , new PropertyMetadata("\uE706", OnGlyphChanged));

    public string Glyph
    {
        get { return (string)GetValue(GlyphProperty); }
        set { SetValue(GlyphProperty, value); }
    }

    private TextBlock GlyphText;

    public SecondaryIconButton(string Glyph)
        : base()
    {
        IsChecked = true;
        this.Glyph = Glyph;
    }

    protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        GlyphText = (TextBlock)GetTemplateChild("OverflowCheckGlyph");
        GlyphText.Width = GlyphText.Height = 16;

        UpdateGlyph();
    }

    // Force the button to always be checked
    protected override void OnPointerReleased(PointerRoutedEventArgs e)
    {
        base.OnPointerReleased(e);
        IsChecked = true;
    }

    private void UpdateGlyph()
    {
        if (GlyphText == null) return;
        GlyphText.Text = Glyph;
    }

    private static void OnGlyphChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((SecondaryIconButton)d).UpdateGlyph();
    }
}

样本

 <CommandBar x:Name="commandbar" RequestedTheme="Dark">
                <CommandBar.SecondaryCommands>
                    <controlEx:SecondaryIconButton Glyph="&#xE109;" RequestedTheme="Dark" 
                                                   Foreground="{StaticResource NavigationPaneText}" 
                                      x:Name="createButton" 
                                      x:Uid="CreateNewItemLabel"></controlEx:SecondaryIconButton>
                    <controlEx:SecondaryIconButton Glyph="&#xE174;" RequestedTheme="Dark" 
                                                   Foreground="{StaticResource NavigationPaneText}" 
                                      x:Name="importExportButton" 
                                      x:Uid="ImportExportLabel" ></controlEx:SecondaryIconButton>
                </CommandBar.SecondaryCommands>
                <CommandBar.PrimaryCommands>

                </CommandBar.PrimaryCommands>
            </CommandBar>