按钮

按钮为用户提供了触发即时操作的方法。 某些按钮专用于特定的任务,例如导航、重复的操作或提供菜单。

按钮示例

Extensible Application Markup Language (XAML) 框架提供了一个标准按钮控件,以及多个专用的按钮控件。

控件 说明
Button 用于启动即时操作的按钮。 可以与 Click 事件或 Command 绑定配合使用。
RepeatButton 一种按钮,在被按下时会持续引发 Click 事件。
HyperlinkButton 一种按钮,其样式设置类似于超链接,用于导航。 有关超链接的详细信息,请参阅超链接
DropDownButton 一种带 V 形图标的按钮,用于打开附加的浮出控件。
SplitButton 一种按钮,分为两端。 一端启动操作,另一端打开菜单。
ToggleSplitButton 一种切换按钮,分为两端。 一端进行开/关切换,另一端打开菜单。
ToggleButton 可以打开或关闭的按钮。

这是正确的控件吗?

用户可以使用 Button 控件启动即时操作,如提交表单。

当操作是导航到另一个页面时,不要使用 Button 控件,应改用 HyperlinkButton 控件。 有关超链接的详细信息,请参阅超链接

重要

对于向导导航,请使用标记为“上一步”和“下一步”的按钮 。 对于其他类型的向后导航或向上导航,请使用“上一步”按钮

当用户可能需要反复触发某个操作时,请使用 RepeatButton 控件。 例如,使用 RepeatButton 控件将计数器中的某个值递增或递减。

当按钮的浮出控件包含多个选项时,使用 DropDownButton 控件。 默认的 V 形以视觉方式提示用户,此按钮包含浮出控件。

如果希望用户能够启动即时操作或从其他选项中独立进行选择,则使用 SplitButton 控件。

如果希望用户能够在两个互斥状态之间进行即时切换,则使用 ToggleButton 控件,而按钮最能满足你的 UI 需求。 除非 UI 适合使用按钮,否则使用 AppBarToggleButtonCheckBoxRadioButtonToggleSwitch 可能会更好。

建议

  • 请确保用户清楚地了解按钮的目的和状态。

  • 有多个按钮用于相同决策时(例如,在确认对话框中),请按以下顺序显示提交按钮,其中,[执行]和[不执行]是对主要说明的具体响应:

    • 确定/[执行]/是
      • [不执行]/否
      • Cancel
  • 一次仅向用户显示一两个按钮,例如,“接受” 和“取消” 。 如果你需要为用户显示更多操作,请考虑使用用户可从中选择操作的复选框单选按钮,并通过一个命令按钮来触发这些操作。

  • 对于需要在应用的多个页面上提供的操作,请考虑使用底部应用栏,而不要在多个页面上重复设置按钮。

按钮文本

按钮内容通常为文本。 在设计该文本时,请使用以下建议:

  • 使用简洁具体而又明晰易懂的文本来清楚地描述按钮可以执行的操作。 通常,按钮文本内容是一个作为动词的单个字词。

  • 请使用默认字体,除非你的品牌指南告诉你使用其他字体。

  • 对于较短的文本,通过使用最小按钮宽度 120px 避免命令按钮过窄。

  • 对于较长的文本,通过将文本最大长度限制为 26 个字符避免命令按钮过宽。

  • 如果按钮的文本内容是动态的(即,它已本地化),请考虑按钮大小将如何调整及其对周围控件的影响。

需要修复:
具有溢出文本的按钮。
并排显示两个按钮的屏幕截图,其中标签都显示:带有 thxt 的按钮
选项 1:
如果文本长度大于 26 个字符,请增加按钮宽度、堆叠按钮和换行。
两个按钮的屏幕截图,其中一个按钮宽度增大,另一个按钮的标签都显示:带 thxt 的按钮将换行。
选项 2:
增加按钮高度并对文本换行。
两个高度并排增加的按钮的屏幕截图,标签都显示:带有可换行的 thxt 的按钮。

如果布局只需一个按钮,则它应基于其容器上下文进行左对齐或右对齐。

  • 只有一个按钮的对话框应使按钮右对齐。 如果对话框只包含一个按钮,请确保该按钮执行安全、无破坏性的操作。 如果使用 ContentDialog 并指定单个按钮,则它会自动右对齐。

    对话框中的按钮

  • 如果按钮出现在容器 UI 中(例如,在 toast 通知、浮出控件或列表视图项目中),则应在容器中使按钮右对齐

    容器中的按钮

  • 在包含单个按钮的页面中(例如,处于设置页面底部的“应用” 按钮),应使按钮左对齐。 这会确保按钮与页面内容的其余部分对齐。

    页面上的按钮

后退按钮

后退按钮是一种系统提供的 UI 元素,可支持在后退堆栈或用户导航历史记录中向后导航。 你无需创建自己的后退按钮,但可能必须进行一些工作才能支持良好的后退导航体验。 有关详细信息,请参阅 Windows 应用的导航历史记录和向后导航

示例

本示例在对话框中使用“保存”、“不保存”和“取消”这三个按钮来询问用户是否要保存工作。

在对话框中使用的按钮示例

UWP 和 WinUI 2

重要

本文中的信息和示例针对使用 Windows 应用 SDKWinUI 3 的应用进行优化,但通常适用于使用 WinUI 2 的 UWP 应用。 有关特定于平台的信息和示例,请参阅 UWP API 参考。

本部分包含你在 UWP 或 WinUI 2 应用中使用该控件所需的信息。

UWP 应用的 DropDownButton、SplitButton 和 ToggleSplitButton 控件作为 Windows UI 库 2 的一部分包含在内。 有关详细信息(包括安装说明),请参阅 Windows UI 库。 这些控件的 API 同时存在于 Windows.UI.Xaml.ControlsMicrosoft.UI.Xaml.Controls 命名空间中。

建议使用最新的 WinUI 2 来获取所有控件的最新样式和模板。 WinUI 2.2 或更高版本包含这些控件的新模板,这些控件使用圆角。 有关详细信息,请参阅圆角半径

若要将本文中的代码与 WinUI 2 配合使用,请在 XAML 中使用别名 (我们使用 muxc) 来表示项目中包含的 Windows UI 库 API。 有关详细信息 ,请参阅 WinUI 2 入门

xmlns:muxc="using:Microsoft.UI.Xaml.Controls"

<muxc:DropDownButton />
<muxc:SplitButton />
<muxc:ToggleSplitButton />

创建按钮

WinUI 3 库应用包括大多数 WinUI 3 控件、特性和功能的交互式示例。 通过 Microsoft Store 获取应用,或在 GitHub 上获取源代码

此示例显示一个响应单击操作的按钮。

在 XAML 中创建按钮。

<Button Content="Subscribe" Click="SubscribeButton_Click"/>

或在代码中创建按钮。

Button subscribeButton = new Button();
subscribeButton.Content = "Subscribe";
subscribeButton.Click += SubscribeButton_Click;

// Add the button to a parent container in the visual tree.
stackPanel1.Children.Add(subscribeButton);

处理 Click 事件。

private async void SubscribeButton_Click(object sender, RoutedEventArgs e)
{
    // Call app specific code to subscribe to the service. For example:
    ContentDialog subscribeDialog = new ContentDialog
    {
        Title = "Subscribe to App Service?",
        Content = "Listen, watch, and play in high definition for only $9.99/month. Free to try, cancel anytime.",
        CloseButtonText = "Not Now",
        PrimaryButtonText = "Subscribe",
        SecondaryButtonText = "Try it"
    };

    ContentDialogResult result = await subscribeDialog.ShowAsync();
}

按钮交互

如果用手指或触笔点击某个 Button 控件,或在指针位于该控件上时按鼠标左键,则按钮会引发 Click 事件。 如果按钮具有键盘焦点,则按 Enter 键或空格键也会引发 Click 事件。

你通常无法处理 Button 对象上的低级别 PointerPressed 事件,因为它具有 Click 行为。 有关详细信息,请参阅事件和路由事件概述

可以通过更改 ClickMode 属性来更改按钮引发 Click 事件的方式。 ClickMode 默认值为 Release,但你也可以将按钮的 ClickMode 值设置为 HoverPress。 如果 ClickModeHover,则无法使用键盘或触控引发 Click 事件。

按钮内容

ButtonContentControl 类的内容控件。 它的 XAML 内容属性为 Content,这对于 XAML 支持如下所示的语法:<Button>A button's content</Button>。 可以将任何对象设置为按钮的内容。 如果内容是一个 UIElement 对象,则会在按钮中呈现它。 如果该内容是另一种类型的对象,则会在按钮中显示其字符串表示形式。

按钮内容通常为文本。 设计该文本时,请遵循前面列出的 按钮文本建议

还可以自定义构成按钮外观的视觉效果。 例如,可以将文本替换为图标,或使用图标以及文本。

在这里,我们将一个包含图像和文本的 StackPanel 设置为按钮内容。

<Button x:Name="Button2" Click="Button_Click" Width="80" Height="90">
    <StackPanel>
        <Image Source="/Assets/Slices.png" Height="52"/>
        <TextBlock Text="Slices" Foreground="Black" HorizontalAlignment="Center"/> 
    </StackPanel>
</Button>

按钮如下所示。

包含图像和文本内容的按钮

创建重复按钮

WinUI 3 库应用包括大多数 WinUI 3 控件、特性和功能的交互式示例。 通过 Microsoft Store 获取应用,或在 GitHub 上获取源代码

RepeatButton 控件是一个从按下时到释放为止重复引发 Click 事件的按钮。 设置 Delay 属性可指定 RepeatButton 控件在其被按下后和开始重复单击操作之间等待的时间。 设置 Interval 属性来指定重复单击操作之间的时间。 两个属性的时间都以毫秒为单位指定。

以下示例显示两个 RepeatButton 控件,两者各自的 Click 事件用于增加和减少文本块中显示的值。

<StackPanel>
    <RepeatButton Width="100" Delay="500" Interval="100" Click="Increase_Click">Increase</RepeatButton>
    <RepeatButton Width="100" Delay="500" Interval="100" Click="Decrease_Click">Decrease</RepeatButton>
    <TextBlock x:Name="clickTextBlock" Text="Number of Clicks:" />
</StackPanel>
private static int _clicks = 0;
private void Increase_Click(object sender, RoutedEventArgs e)
{
    _clicks += 1;
    clickTextBlock.Text = "Number of Clicks: " + _clicks;
}

private void Decrease_Click(object sender, RoutedEventArgs e)
{
    if(_clicks > 0)
    {
        _clicks -= 1;
        clickTextBlock.Text = "Number of Clicks: " + _clicks;
    }
}

创建下拉按钮

WinUI 3 库应用包括大多数 WinUI 3 控件、特性和功能的交互式示例。 通过 Microsoft Store 获取应用,或在 GitHub 上获取源代码

DropDownButton 是一个按钮,它显示一个 V 形图标作为视觉指示器,表明其附加的浮出控件包含更多选项。 其行为与包含浮出控件的标准 Button 控件相同,仅外观存在差异。

该下拉按钮继承了 Click 事件,但你通常不使用它, 而是使用 Flyout 属性附加一个浮出控件,并使用浮出控件中的菜单选项来调用操作。 单击按钮时,浮出控件会自动打开。 请务必指定浮出控件的 Placement 属性,确保与按钮相关的放置符合需要。 默认的放置算法不一定在所有情况下都能确保放置符合需求。 有关浮出控件的详细信息,请参阅 浮出控件菜单浮出控件和菜单栏

示例 - 下拉按钮

此示例演示如何创建带浮出控件的下拉按钮,该控件包含的命令用于在 RichEditBox 控件中进行段落对齐。 (有关详细信息和代码,请参阅富编辑框)。

包含对齐命令的下拉按钮

<DropDownButton ToolTipService.ToolTip="Alignment">
    <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="14" Text="&#xE8E4;"/>
    <DropDownButton.Flyout>
        <MenuFlyout Placement="BottomEdgeAlignedLeft">
            <MenuFlyoutItem Text="Left" Icon="AlignLeft" Tag="left"
                            Click="AlignmentMenuFlyoutItem_Click"/>
            <MenuFlyoutItem Text="Center" Icon="AlignCenter" Tag="center"
                            Click="AlignmentMenuFlyoutItem_Click"/>
            <MenuFlyoutItem Text="Right" Icon="AlignRight" Tag="right"
                            Click="AlignmentMenuFlyoutItem_Click"/>
        </MenuFlyout>
    </DropDownButton.Flyout>
</DropDownButton>
private void AlignmentMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
{
    var option = ((MenuFlyoutItem)sender).Tag.ToString();

    Windows.UI.Text.ITextSelection selectedText = editor.Document.Selection;
    if (selectedText != null)
    {
        // Apply the alignment to the selected paragraphs.
        var paragraphFormatting = selectedText.ParagraphFormat;
        if (option == "left")
        {
            paragraphFormatting.Alignment = Windows.UI.Text.ParagraphAlignment.Left;
        }
        else if (option == "center")
        {
            paragraphFormatting.Alignment = Windows.UI.Text.ParagraphAlignment.Center;
        }
        else if (option == "right")
        {
            paragraphFormatting.Alignment = Windows.UI.Text.ParagraphAlignment.Right;
        }
    }
}

创建拆分按钮

WinUI 3 库应用包括大多数 WinUI 3 控件、特性和功能的交互式示例。 通过 Microsoft Store 获取应用,或在 GitHub 上获取源代码

SplitButton 控件有两个可以分别调用的部分。 一个部分的行为类似于标准按钮,可以调用即时操作。 另一个部分调用浮出控件,该控件包含可供用户选择的其他选项。

注意

以触控方式调用时,拆分按钮的行为与下拉按钮一样;按钮的两部分都会调用浮出控件。 使用其他输入方式时,用户可以单独调用按钮的任一部分。

拆分按钮的典型行为如下:

  • 当用户单击按钮部分时,处理 Click 事件来调用当前已在下拉列表中选中的选项。

  • 当下拉列表打开时,处理下拉列表中项的调用,更改所选的选项,然后调用它。 必须调用浮出控件项,因为在使用触控时不发生按钮 Click 事件。

提示

可以通过多种方式将项置于下拉列表中并处理其调用。 如果使用 ListViewGridView,一种方式是处理 SelectionChanged 事件。 如果这样做,请将 SingleSelectionFollowsFocus 设置为 false。 这样用户就可以使用键盘来导航选项,在每次变换选项时不会调用项。

示例 - 拆分按钮

此示例演示如何创建拆分按钮,该按钮用于更改 RichEditBox 控件中所选文本的前景色。 (有关详细信息和代码,请参阅富编辑框)。 拆分按钮的浮出控件使用 BottomEdgeAlignedLeft 作为其 Placement 属性的默认值。 不能覆盖此值。

用于选择前景色的拆分按钮

<SplitButton ToolTipService.ToolTip="Foreground color"
             Click="BrushButtonClick">
    <Border x:Name="SelectedColorBorder" Width="20" Height="20"/>
    <SplitButton.Flyout>
        <Flyout x:Name="BrushFlyout">
            <!-- Set SingleSelectionFollowsFocus="False"
                 so that keyboard navigation works correctly. -->
            <GridView ItemsSource="{x:Bind ColorOptions}"
                      SelectionChanged="BrushSelectionChanged"
                      SingleSelectionFollowsFocus="False"
                      SelectedIndex="0" Padding="0">
                <GridView.ItemTemplate>
                    <DataTemplate>
                        <Rectangle Fill="{Binding}" Width="20" Height="20"/>
                    </DataTemplate>
                </GridView.ItemTemplate>
                <GridView.ItemContainerStyle>
                    <Style TargetType="GridViewItem">
                        <Setter Property="Margin" Value="2"/>
                        <Setter Property="MinWidth" Value="0"/>
                        <Setter Property="MinHeight" Value="0"/>
                    </Style>
                </GridView.ItemContainerStyle>
            </GridView>
        </Flyout>
    </SplitButton.Flyout>
</SplitButton>
public sealed partial class MainPage : Page
{
    // Color options that are bound to the grid in the split button flyout.
    private List<SolidColorBrush> ColorOptions = new List<SolidColorBrush>();
    private SolidColorBrush CurrentColorBrush = null;

    public MainPage()
    {
        this.InitializeComponent();

        // Add color brushes to the collection.
        ColorOptions.Add(new SolidColorBrush(Colors.Black));
        ColorOptions.Add(new SolidColorBrush(Colors.Red));
        ColorOptions.Add(new SolidColorBrush(Colors.Orange));
        ColorOptions.Add(new SolidColorBrush(Colors.Yellow));
        ColorOptions.Add(new SolidColorBrush(Colors.Green));
        ColorOptions.Add(new SolidColorBrush(Colors.Blue));
        ColorOptions.Add(new SolidColorBrush(Colors.Indigo));
        ColorOptions.Add(new SolidColorBrush(Colors.Violet));
        ColorOptions.Add(new SolidColorBrush(Colors.White));
    }

    private void BrushButtonClick(object sender, object e)
    {
        // When the button part of the split button is clicked,
        // apply the selected color.
        ChangeColor();
    }

    private void BrushSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        // When the flyout part of the split button is opened and the user selects
        // an option, set their choice as the current color, apply it, then close the flyout.
        CurrentColorBrush = (SolidColorBrush)e.AddedItems[0];
        SelectedColorBorder.Background = CurrentColorBrush;
        ChangeColor();
        BrushFlyout.Hide();
    }

    private void ChangeColor()
    {
        // Apply the color to the selected text in a RichEditBox.
        Windows.UI.Text.ITextSelection selectedText = editor.Document.Selection;
        if (selectedText != null)
        {
            Windows.UI.Text.ITextCharacterFormat charFormatting = selectedText.CharacterFormat;
            charFormatting.ForegroundColor = CurrentColorBrush.Color;
            selectedText.CharacterFormat = charFormatting;
        }
    }
}

创建切换式拆分按钮

WinUI 3 库应用包括大多数 WinUI 3 控件、特性和功能的交互式示例。 通过 Microsoft Store 获取应用,或在 GitHub 上获取源代码

ToggleSplitButton 控件有两个可以分别调用的部分。 一个部分的行为类似于可以打开或关闭的切换按钮。 另一个部分调用浮出控件,该控件包含可供用户选择的其他选项。

切换式拆分按钮通常用于启用或禁用某项功能,该功能有多个可供用户选择的选项。 例如,在文档编辑器中,可以使用它来打开或关闭列表,而下拉按钮则用来选择列表的样式。

注意

以触控方式调用时,切换式拆分按钮的行为与下拉按钮一样。 使用其他输入方式时,用户可以切换并单独调用按钮的两个部分。 使用触控时,按钮的两部分都会调用浮出控件。 因此,必须在浮出控件中包括一个用来通过切换方式打开或关闭按钮的选项。

与 ToggleButton 的差异

ToggleButton 不一样,ToggleSplitButton 没有不确定状态。 因此,应注意以下差异:

  • ToggleSplitButton 没有 IsThreeState 属性或 Indeterminate 事件。
  • ToggleSplitButton.IsChecked 属性只是一个布尔值,而不是可为 Null 的<布尔>值。
  • ToggleSplitButton 只有 IsCheckedChanged 事件,没有单独的 CheckedUnchecked 事件。

示例 - 切换式拆分按钮

以下示例演示如何在 RichEditBox 控件中使用切换式拆分按钮来启用或禁用列表格式设置,以及更改列表的样式。 (有关详细信息和代码,请参阅富编辑框)。 切换式拆分按钮的浮出控件使用 BottomEdgeAlignedLeft 作为其 Placement 属性的默认值。 不能覆盖此值。

用于选择列表样式的切换式拆分按钮

<ToggleSplitButton x:Name="ListButton"
                   ToolTipService.ToolTip="List style"
                   Click="ListButton_Click"
                   IsCheckedChanged="ListStyleButton_IsCheckedChanged">
    <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="14" Text="&#xE8FD;"/>
    <ToggleSplitButton.Flyout>
        <Flyout>
            <ListView x:Name="ListStylesListView"
                      SelectionChanged="ListStylesListView_SelectionChanged"
                      SingleSelectionFollowsFocus="False">
                <StackPanel Tag="bullet" Orientation="Horizontal">
                    <FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE7C8;"/>
                    <TextBlock Text="Bullet" Margin="8,0"/>
                </StackPanel>
                <StackPanel Tag="alpha" Orientation="Horizontal">
                    <TextBlock Text="A" FontSize="24" Margin="2,0"/>
                    <TextBlock Text="Alpha" Margin="8"/>
                </StackPanel>
                <StackPanel Tag="numeric" Orientation="Horizontal">
                    <FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xF146;"/>
                    <TextBlock Text="Numeric" Margin="8,0"/>
                </StackPanel>
                <TextBlock Tag="none" Text="None" Margin="28,0"/>
            </ListView>
        </Flyout>
    </ToggleSplitButton.Flyout>
</ToggleSplitButton>
private void ListStyleButton_IsCheckedChanged(ToggleSplitButton sender, ToggleSplitButtonIsCheckedChangedEventArgs args)
{
    // Use the toggle button to turn the selected list style on or off.
    if (((ToggleSplitButton)sender).IsChecked == true)
    {
        // On. Apply the list style selected in the drop down to the selected text.
        var listStyle = ((FrameworkElement)(ListStylesListView.SelectedItem)).Tag.ToString();
        ApplyListStyle(listStyle);
    }
    else
    {
        // Off. Make the selected text not a list,
        // but don't change the list style selected in the drop down.
        ApplyListStyle("none");
    }
}

private void ListStylesListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var listStyle = ((FrameworkElement)(e.AddedItems[0])).Tag.ToString();

    if (ListButton.IsChecked == true)
    {
        // Toggle button is on. Turn it off...
        if (listStyle == "none")
        {
            ListButton.IsChecked = false;
        }
        else
        {
            // or apply the new selection.
            ApplyListStyle(listStyle);
        }
    }
    else
    {
        // Toggle button is off. Turn it on, which will apply the selection
        // in the IsCheckedChanged event handler.
        ListButton.IsChecked = true;
    }
}

private void ApplyListStyle(string listStyle)
{
    Windows.UI.Text.ITextSelection selectedText = editor.Document.Selection;
    if (selectedText != null)
    {
        // Apply the list style to the selected text.
        var paragraphFormatting = selectedText.ParagraphFormat;
        if (listStyle == "none")
        {  
            paragraphFormatting.ListType = Windows.UI.Text.MarkerType.None;
        }
        else if (listStyle == "bullet")
        {
            paragraphFormatting.ListType = Windows.UI.Text.MarkerType.Bullet;
        }
        else if (listStyle == "numeric")
        {
            paragraphFormatting.ListType = Windows.UI.Text.MarkerType.Arabic;
        }
        else if (listStyle == "alpha")
        {
            paragraphFormatting.ListType = Windows.UI.Text.MarkerType.UppercaseEnglishLetter;
        }
        selectedText.ParagraphFormat = paragraphFormatting;
    }
}

获取示例代码

  • WinUI 库:此示例以交互式格式显示所有 XAML 控件。