当用户进入已选择某个单选按钮的列表时,所选单选按钮会获得焦点。
没有选项卡焦点的列表
具有初始选项卡焦点的列表
有关常规键盘导航行为的详细信息,请参阅
键盘交互 - 导航
。
如果
RadioButtons
组中的某个项已具有焦点,则用户可以使用箭头键在组内的各个项之间进行“内部导航”。 可使用向上键和向下键移动到“上一个”或“下一个”逻辑项,就像 XAML 标记中定义的那样。 使用向左键和向右键可进行空间移动。
在单列或单行布局中导航
在单列或单行布局中,键盘导航会导致以下行为:
向上键和向下键在项之间移动。
向左箭头和向右箭头键不执行任何操作。
使用向左键和向上键可移动到前一项,使用向右键和向下键可移动到下一项。
在多列、多行布局中导航
在多列、多行网格布局中,键盘导航会导致以下行为:
向左键/向右键
使用向左键和向右键可让焦点在同一行中的项之间水平移动。
当焦点位于某列的最后一项并按下向右键或向左键时,焦点会移至下一列或上一列(如果有)中的最后一项。
向上键/向下键
使用向上键和向下键可让焦点在同一列中的项之间垂直移动。
当焦点位于某列的最后一项并按下向下键时,焦点会移至下一列(如果有)的第一项。 当焦点位于某列的第一项且按下向上键时,焦点会移至上一列(如果有)的最后一个项
有关详细信息,请参阅
键盘交互
。
RadioButtons 组不会将焦点从第一行或第一列换行到最后一行或最后一列,也不会从最后一行或最后一列换行到第一行或最后一列。 这是因为在用户使用屏幕阅读器时,会失去边界检测和清晰的开始和结束指示,这让有视力障碍的用户难以导航列表。
RadioButtons
控件也不支持枚举,因为该控件用于包含合理数量的项(请参阅
这是正确的控件吗?
)。
选择跟随焦点
使用键盘在
RadioButtons
组中的各项之间导航时,随着焦点从一个项移到下一个项,将选择新获得焦点的项,并清除之前的焦点项。
键盘导航之前
键盘导航之前的焦点和选择。
键盘导航之后
键盘导航之后的焦点和选择,其中通过向下键将焦点移到单选按钮 3,选择它,并清除单选按钮 2。
通过使用 Ctrl + 箭头键导航,可以在不更改选择的情况下移动焦点。 移动焦点后,可以使用空格键选择当前具有焦点的项。
使用游戏手柄和遥控器导航
如果使用游戏手柄或遥控器在单选按钮之间移动,则会禁用“跟随焦点选择”行为,用户必须按“A”按钮才可选择当前聚焦的单选按钮。
辅助功能行为
下表说明讲述人如何处理
RadioButtons
组和播放的内容。 此行为取决于用户如何设置讲述人详细信息首选项。
讲述人播放内容
讲述人为每个项播放的“名称”
是
AutomationProperties.Name
附加属性的值(如果该项具有此属性);否则,它是项的
ToString
方法返回的值。
x
是当前项在组中的位置。
N
是组中的总项数。
UWP 和 WinUI 2
本文中的信息和示例是针对使用
Windows App SDK
和
WinUI 3
的应用优化的,但通常适用于使用
WinUI 2
的 UWP 应用。 有关特定于平台的信息和示例,请查看 UWP API 参考。
本部分包含在 UWP 或 WinUI 2 应用中使用该控件所需的信息。
用于 UWP 应用的 RadioButtons 控件是 WinUI 2 的一部分。 有关详细信息(包括安装说明),请参阅
WinUI 2
。 这些控件的 API 同时存在于
Windows.UI.Xaml.Controls
和
Microsoft.UI.Xaml.Controls
命名空间中。
UWP API
:
RadioButton 类
、
IsChecked 属性
、
Checked 事件
WinUI 2 API
:
RadioButtons 类
、
SelectedItem 属性
、
SelectedIndex 属性
、
SelectionChanged 事件
打开 WinUI 3 库应用并查看“Button”操作
。
WinUI 2 库
应用包括大多数 WinUI 2 控件、特性和功能的交互式示例。 通过
Microsoft Store
获取应用,或在
GitHub
上获取源代码。
可以通过两种方法创建单选按钮组。
从 WinUI 2.3 开始,我们建议使用
RadioButtons
控件。 此控件可简化布局、处理键盘导航和辅助功能,并支持绑定到数据源。
你可以使用由单独的
RadioButton
控件组成的组。 如果你的应用未使用 WinUI 2.3 或更高版本,这是唯一的选择。
建议使用最新的
WinUI 2
来获取所有控件的最新样式和模板。
要将本文中的代码与 WinUI 2 配合使用,请使用 XAML 中的别名(我们使用
muxc
)来表示项目中包含的 Windows UI 库 API。 有关详细信息,请参阅
WinUI 2 入门
。
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
<muxc:RadioButtons />
重要 API:RadioButtons 类、 SelectedItem 属性、SelectedIndex 属性、SelectionChanged 事件、RadioButton 类、IsChecked 属性、Checked 事件
打开 WinUI 2 库应用并查看“RadioButton”操作。 WinUI 2 库应用包括大多数 WinUI 2 控件、特性和功能的交互式示例。 通过 Microsoft Store 获取应用,或在 GitHub 上获取源代码。
RadioButtons
控件使用类似于 ItemsControl 的内容模型。 这意味着你可以:
通过直接向 Items 集合添加项或将数据绑定到其 ItemsSource 属性来填充该控件。
使用 SelectedIndex 或 SelectedItem 属性来获取和设置所选的选项。
处理 SelectionChanged 事件,以便在选择某个选项时执行操作。
此处,你声明了一个包含三个选项的简单 RadioButtons
控件。 Header 属性设置为向组提供标签,SelectedIndex
属性设置为提供默认选项。
<RadioButtons Header="Background color"
SelectedIndex="0"
SelectionChanged="BackgroundColor_SelectionChanged">
<x:String>Red</x:String>
<x:String>Green</x:String>
<x:String>Blue</x:String>
</RadioButtons>
结果类似以下形式:
要在用户选择某个选项时执行操作,请处理 SelectionChanged 事件。 在此处,更改名为“ExampleBorder”的 Border 元素的背景色 (<Border x:Name="ExampleBorder" Width="100" Height="100"/>
)。
private void BackgroundColor_SelectionChanged(object sender, SelectionChangedEventArgs e)
if (ExampleBorder != null && sender is RadioButtons rb)
string colorName = rb.SelectedItem as string;
switch (colorName)
case "Red":
ExampleBorder.Background = new SolidColorBrush(Colors.Red);
break;
case "Green":
ExampleBorder.Background = new SolidColorBrush(Colors.Green);
break;
case "Blue":
ExampleBorder.Background = new SolidColorBrush(Colors.Blue);
break;
还可以从 SelectionChangedEventArgs.AddedItems 属性获取所选项。 在索引 0 处只有一个所选项,因此可以按如下所示来获取它:string colorName = e.AddedItems[0] as string;
。
单选按钮有两个状态:已选择或已清除。 当在 RadioButtons
组中选择某个选项时,可以从 SelectedItem 属性获取其值,从 SelectedIndex 属性获取其在集合中的位置。 如果用户选择了同一组中的另一个单选按钮,则可以清除单选按钮,但如果用户再次选择它,则无法将其清除。 但是,可以通过设置 SelectedItem = null
或 SelectedIndex = -1
,以编程方式清除单选按钮组。 (如果将 SelectedIndex
设置为 Items
集合范围之外的任何值,则不会选择任何内容。)
RadioButtons 内容
前面的示例使用简单的字符串填充了 RadioButtons
控件。 该控件提供了单选按钮,并使用字符串作为每个单选按钮的标签。
但是,你可以用任何对象填充 RadioButtons
控件。 通常,你希望对象提供可以用作文本标签的字符串表示形式。 在某些情况下,图像可能适合代替文本。
此处,SymbolIcon 元素用于填充控件。
<RadioButtons Header="Select an icon option:">
<SymbolIcon Symbol="Back"/>
<SymbolIcon Symbol="Attach"/>
<SymbolIcon Symbol="HangUp"/>
<SymbolIcon Symbol="FullScreen"/>
</RadioButtons>
还可以使用单独的 RadioButton 控件来填充 RadioButtons
项。 我们稍后将讨论这种特殊情况。 请参阅 RadioButtons 组中的 RadioButton 控件。
能够使用任何对象的好处是可以将 RadioButtons
控件绑定到数据模型中的自定义类型。 下一节将对此进行说明。
RadioButtons
控件支持将数据绑定到其 ItemsSource 属性。 此示例显示如何将控件绑定到自定义数据源。 此示例的外观和功能与前面的背景色示例相同,但此处,颜色画笔存储在数据模型中,而不是在 SelectionChanged
事件处理程序中创建。
<RadioButtons Header="Background color"
SelectedIndex="0"
SelectionChanged="BackgroundColor_SelectionChanged"
ItemsSource="{x:Bind colorOptionItems}"/>
public sealed partial class MainPage : Page
// Custom data item.
public class ColorOptionDataModel
public string Label { get; set; }
public SolidColorBrush ColorBrush { get; set; }
public override string ToString()
return Label;
List<ColorOptionDataModel> colorOptionItems;
public MainPage1()
this.InitializeComponent();
colorOptionItems = new List<ColorOptionDataModel>();
colorOptionItems.Add(new ColorOptionDataModel()
{ Label = "Red", ColorBrush = new SolidColorBrush(Colors.Red) });
colorOptionItems.Add(new ColorOptionDataModel()
{ Label = "Green", ColorBrush = new SolidColorBrush(Colors.Green) });
colorOptionItems.Add(new ColorOptionDataModel()
{ Label = "Blue", ColorBrush = new SolidColorBrush(Colors.Blue) });
private void BackgroundColor_SelectionChanged(object sender, SelectionChangedEventArgs e)
var option = e.AddedItems[0] as ColorOptionDataModel;
ExampleBorder.Background = option?.ColorBrush;
可以使用单独的 RadioButton 控件来填充 RadioButtons
项。 你可能会通过此操作来访问某些属性(如 AutomationProperties.Name
);或者,你可能已有 RadioButton
代码,但想要利用 RadioButtons
的布局和导航。
<RadioButtons Header="Background color">
<RadioButton Content="Red" Tag="red" AutomationProperties.Name="red"/>
<RadioButton Content="Green" Tag="green" AutomationProperties.Name="green"/>
<RadioButton Content="Blue" Tag="blue" AutomationProperties.Name="blue"/>
</RadioButtons>
使用 RadioButtons
组中的 RadioButton
控件时,RadioButtons
控件知道如何表示 RadioButton
,因此你最终不会做出两个选择。
但是,你应该注意一些行为。 我们建议你在单个控件或 RadioButtons
上处理状态和事件,但不能同时在这两者之上进行处理,以避免冲突。
下表显示了这两个控件上的相关事件和属性。
RadioButton
RadioButtons
如果在单个 RadioButton
上处理事件(例如 Checked
或 Unchecked
),并且同时处理 RadioButtons.SelectionChanged
事件,则两个事件都将触发。 RadioButton
事件首先发生,RadioButtons.SelectionChanged
事件随后发生,这可能会导致冲突。
IsChecked
、SelectedItem
和 SelectedIndex
属性保持同步。 对一个属性的更改将更新其他两个属性。
将忽略 RadioButton.GroupName 属性。 组是由 RadioButtons
控件创建的。
默认情况下,RadioButtons
控件在单个列中垂直排列其单选按钮。 可以设置 MaxColumns 属性,使控件在多个列中排列单选按钮。 (执行此操作时,单选按钮按列主序顺序排列,即各个项按照从上到下、然后从左到右的顺序填充。)
<RadioButtons Header="RadioButtons in columns" MaxColumns="3">
<x:String>Item 1</x:String>
<x:String>Item 2</x:String>
<x:String>Item 3</x:String>
<x:String>Item 4</x:String>
<x:String>Item 5</x:String>
<x:String>Item 6</x:String>
</RadioButtons>
将每个单选按钮上的 GroupName 属性设置为相同的值。
在此示例中,第一个单选按钮组依据位于相同的堆栈面板中来进行隐式分组。 第二组分为两个堆栈面板,因此使用 GroupName
将它们显式分组为单个组。
<StackPanel>
<StackPanel>
<TextBlock Text="Background" Style="{ThemeResource BaseTextBlockStyle}"/>
<!-- Group 1 - implicit grouping -->
<StackPanel Orientation="Horizontal">
<RadioButton Content="Green" Tag="green" Checked="BGRadioButton_Checked"/>
<RadioButton Content="Yellow" Tag="yellow" Checked="BGRadioButton_Checked"/>
<RadioButton Content="White" Tag="white" Checked="BGRadioButton_Checked"
IsChecked="True"/>
</StackPanel>
</StackPanel>
<StackPanel>
<TextBlock Text="BorderBrush" Style="{ThemeResource BaseTextBlockStyle}"/>
<!-- Group 2 - grouped by GroupName -->
<StackPanel Orientation="Horizontal">
<StackPanel>
<RadioButton Content="Green" Tag="green" GroupName="BorderBrush"
Checked="BorderRadioButton_Checked"/>
<RadioButton Content="Yellow" Tag="yellow" GroupName="BorderBrush"
Checked="BorderRadioButton_Checked" IsChecked="True"/>
<RadioButton Content="White" Tag="white" GroupName="BorderBrush"
Checked="BorderRadioButton_Checked"/>
</StackPanel>
</StackPanel>
</StackPanel>
<Border x:Name="ExampleBorder"
BorderBrush="#FFFFD700" Background="#FFFFFFFF"
BorderThickness="10" Height="50" Margin="0,10"/>
</StackPanel>
private void BGRadioButton_Checked(object sender, RoutedEventArgs e)
RadioButton rb = sender as RadioButton;
if (rb != null && ExampleBorder != null)
string colorName = rb.Tag.ToString();
switch (colorName)
case "yellow":
ExampleBorder.Background = new SolidColorBrush(Colors.Yellow);
break;
case "green":
ExampleBorder.Background = new SolidColorBrush(Colors.Green);
break;
case "white":
ExampleBorder.Background = new SolidColorBrush(Colors.White);
break;
private void BorderRadioButton_Checked(object sender, RoutedEventArgs e)
RadioButton rb = sender as RadioButton;
if (rb != null && ExampleBorder != null)
string colorName = rb.Tag.ToString();
switch (colorName)
case "yellow":
ExampleBorder.BorderBrush = new SolidColorBrush(Colors.Gold);
break;
case "green":
ExampleBorder.BorderBrush = new SolidColorBrush(Colors.DarkGreen);
break;
case "white":
ExampleBorder.BorderBrush = new SolidColorBrush(Colors.White);
break;
这两组 RadioButton
控件如下所示:
单选按钮有两个状态:已选择或已清除。 选择单选按钮时,其 IsChecked 属性为 true
。 清除单选按钮时,其 IsChecked
属性为 false
。 如果用户选择了同一组中的另一个单选按钮,则可以清除单选按钮,但如果用户再次选择它,则无法将其清除。 但是,你可以通过将单选按钮的 IsChecked
属性设置为 false
,以编程方式清除它。
要考虑的视觉对象
各 RadioButton
控件的默认间距与 RadioButtons
组提供的间距不同。 要将 RadioButtons
间距应用于各 RadioButton
控件,请使用 Margin
值 0,0,7,3
,如下所示。
<StackPanel>
<StackPanel.Resources>
<Style TargetType="RadioButton">
<Setter Property="Margin" Value="0,0,7,3"/>
</Style>
</StackPanel.Resources>
<TextBlock Text="Background"/>
<RadioButton Content="Item 1"/>
<RadioButton Content="Item 2"/>
<RadioButton Content="Item 3"/>
</StackPanel>
下图显示了组中单选按钮的首选间距。