單選按鈕,也稱為選項按鈕,讓使用者從互斥但相關的兩個或多個選項集合中選取一個選項。 單選按鈕一律用於群組中,而且每個選項都會以群組中的一個單選按鈕表示。
在預設狀態下,不會選取 RadioButtons 群組中的單選鈕。 也就是說,會清除所有單選按鈕。 不過,一旦用戶選取單選按鈕,使用者就無法取消選取按鈕,將群組還原為其初始清除狀態。
RadioButtons 群組的單一行為會區分它與 複選框,其支援多重選取和取消選取或清除。
這是正確的控制嗎?
使用單選按鈕讓使用者從兩個以上互斥的選項中進行選擇。
當使用者在進行選取之前需要查看所有選項時,請使用單選按鈕。 單選按鈕均等地強調所有選項,這表示某些選項可能會引起比必要或需要的更多注意。
除非所有選項都值得同等注意,否則請考慮使用其他控件。 例如,若要建議大部分使用者的單一最佳選項,而且在大部分情況下,請使用 下拉式方塊 將該最佳選項顯示為默認選項。
如果只有兩個選項可以清楚地表示為單一的二元選擇,例如開啟/關閉或是/否,請將它們合併成單一的 複選框 或 切換開關 控件。 例如,針對 「我同意」使用單一複選框,而不是使用 「我同意」和「我不同意」的兩個單選按鈕。
請勿針對單一二進位選擇使用兩個單選按鈕:
請改用複選框:
當使用者可以選取多個選項時,請使用 複選框。
當使用者的選項位於值範圍內時(例如 10、20、30...100),使用 滑桿 控件。
如果超過八個選項,請使用 組合方塊。
如果可用的選項是以應用程式的目前內容為基礎,否則可能會動態變化,請使用清單控制項。
Recommendations
- 請確保一組單選按鈕的目的和當前狀態明確。
- 將單選按鈕的文字標籤限制為單行。
- 如果文字標籤是動態的,請考慮按鈕將如何自動調整大小,以及周圍的視覺元素會發生什麼情況。
- 除非您的品牌指導方針另有指示,否則請使用預設字型。
- 不要並排放置兩個 RadioButtons 群組。 當兩個 RadioButtons 群組彼此相鄰時,使用者很難判斷哪些按鈕屬於哪個群組。
RadioButtons 概觀
RadioButtons 對 RadioButton
有兩種方式可以建立單選按鈕群組:RadioButtons 和 RadioButton。
- 我們建議 RadioButtons 控件。 此控制項可簡化版面配置、處理鍵盤瀏覽和輔助功能,並支援系結至數據源。
- 您可以將個別的 RadioButton 組合成控件群組。
鍵盤存取和瀏覽行為已在 RadioButtons 控制項中優化。 這些改進有助於輔助工具使用者及鍵盤高手更快速且輕鬆地瀏覽選項清單。
除了這些改進之外,RadioButtons 群組中個別單選按鈕的預設視覺版面配置已透過自動方向、間距及邊距設定進行優化。 此優化消除了指定這些屬性的需求,因為當您使用更基本的群組控制項時,可能需要這麼做,例如 StackPanel 或 Grid。
流覽 RadioButtons 群組
控制件 RadioButtons 具有特殊的瀏覽行為,可協助鍵盤使用者更快速且更輕鬆地瀏覽清單。
鍵盤焦點
控制項 RadioButtons 支援兩種狀態:
- 沒有任何單選按鈕被選取
- 一個單選按鈕已被選取
下一節說明控件在每個狀態中的焦點行為。
沒有任何單選按鈕被選取
未選取單選按鈕時,清單中的第一個單選按鈕會取得焦點。
備註
初始索引標籤導覽後接收索引標籤焦點的專案未被選取。
沒有索引標籤焦點的清單、沒有選取專案
具有初始索引標籤焦點的清單,沒有選取專案
一個單選按鈕已被選取
當使用者使用 Tab 鍵進入已有選取的單選按鈕的清單時,選取的單選按鈕會取得焦點。
沒有索引標籤焦點的清單
清單具有初始索引標籤焦點
鍵盤導覽
如需一般鍵盤瀏覽行為的詳細資訊,請參閱 鍵盤互動 - 流覽。
當群組中的 RadioButtons 專案已經有焦點時,使用者可以使用箭頭鍵在群組內的專案之間進行「內部流覽」。 向上箭頭鍵和向下箭頭鍵會移至 XAML 標記中所定義的「下一個」或「上一個」邏輯項目。 箭頭鍵中的左鍵和右鍵用於空間移動。
在單一欄或單一列版面配置中導航
在單欄或單一數據列配置中,鍵盤瀏覽會產生下列行為:
單一數據行
向上鍵和向下鍵會在項目之間移動。
向左鍵和向右鍵不會執行任何動作。
單一數據列
向左鍵和向上鍵會移至上一個專案,而向右鍵和向下鍵則移至下一個專案。
在多欄、多列版面配置中導航
在多欄、多列網格線配置中,鍵盤流覽會導致此行為:
左/右箭頭鍵
左右箭頭鍵在一行的項目之間水平移動焦點。
當焦點位於數據行的最後一個專案,按下向右鍵或向左鍵時,焦點會移至下一個或上一欄的最後一個專案(如果有的話)。
向上/向下鍵
上下箭頭鍵會在欄中項目之間垂直移動焦點。
當焦點位於欄的最後一個專案時,按下向下箭頭鍵,焦點會移至下一欄的第一個專案(如果有的話)。 當焦點位於欄中的第一個專案上,按下向上鍵時,焦點會移至上一欄的最後一個專案(如果有的話)
如需詳細資訊,請參閱 鍵盤互動。
包裝
RadioButtons 群組不會將焦點從第一列或第一行循環到最後列或最後行,也不會將焦點從最後列或最後行循環到第一列或第一行。 這是因為,當使用者使用螢幕助讀程式時,界限感和清楚的開始和結束指示遺失,這使得視覺障礙的使用者難以瀏覽清單。
控件 RadioButtons 也不支援列舉,因為控件的目的是要包含合理的項目數(請參閱 這是正確的控件嗎?)。
焦點後進行選取
當您使用鍵盤在群組中的 RadioButtons 項目之間巡覽時,當焦點從某個專案移至下一個專案時,會選取新焦點的專案,並清除先前的焦點專案。
在鍵盤瀏覽 之前
鍵盤導航前的焦點和選擇。
在鍵盤流覽之後
使用鍵盤瀏覽後的焦點和選擇,其中向下箭頭鍵會將焦點移至單選按鈕 3,選取該按鈕,並清除單選按鈕 2。
您可以使用 Ctrl+箭頭鍵來流覽,而不需變更選取範圍即可移動焦點。 移動焦點之後,您可以使用空格鍵來選取目前具有焦點的專案。
使用遊戲手柄和遙控器操作
如果您使用遊戲控制器或遙控器在單選鈕之間移動,「選擇跟隨焦點」行為將被停用,而且用戶必須按下「A」按鈕來選擇目前具有焦點的單選鈕。
輔助功能行為
下表說明朗讀程式如何處理 RadioButtons 群組,以及所宣布的內容。 此行為取決於使用者如何設定朗讀程式的細節偏好設定。
| 行動 | 旁白公告 |
|---|---|
| 焦點移至選取的專案 | “name,RadioButton,selected,x of N” |
| 焦點移至未選取的專案 (如果使用 Ctrl 加箭頭鍵或 Xbox 遊戲板瀏覽,) 表示選取項目未跟隨焦點。) |
"name,單選按鈕,未選擇,x of N" |
備註
旁白針對每個項目宣告的 名稱,是該項目的 AutomationProperties.Name 附加屬性的值(如果該屬性可用);否則,則為項目的 ToString 方法所返回的值。
x 是目前項目的數目。 N 是群組中的項目總數。
建立 WinUI RadioButtons 群組
WinUI 3 Gallery 應用程式包含大部分 WinUI 3 控制項、特性和功能的互動式範例。 從 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 事件。 在這裡,您會變更 Border 元素的背景 色彩,名為 “ExampleBorder” (<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>
您也可以使用個別 單選按鈕 控件來填入 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;
}
}
RadioButtons 群組中的 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>
當您在 RadioButton 群組中使用 RadioButtons 控件時,RadioButtons 控件知道如何呈現 RadioButton,因此最後不會有兩個選取圓形。
不過,您應該注意某些行為。 建議您處理個別控件或 RadioButtons上的狀態和事件,但不要同時處理,以避免衝突。
下表顯示這兩個控件的相關事件和屬性。
| RadioButton | 單選按鈕 |
|---|---|
| 核取,未核取,點擊 | 選擇已更改 |
| 已檢查 | SelectedItemSelectedIndex |
如果您處理個別 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>
小提示
若要將項目排列在單一水平一列中,請設定 MaxColumns 為該組中的項目數目。
建立您自己的 RadioButton 群組
這很重要
我們建議使用 RadioButtons 控件來群組 RadioButton 元素。
單選按鈕會在群組中運作。 您可以使用下列兩種方式之一將個別 RadioButton 控制項分組:
- 將它們放在相同的父容器內。
- 將每個單選按鈕上的 GroupName 屬性設定為相同的值。
在此範例中,第一組單選按鈕會自動分組,因為它們位於相同的 StackPanel 中。 第二個群組被分散在兩個堆疊面板中,所以使用 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>
下列影像顯示群組中單選按鈕的慣用間距。
備註
如果您使用 WinUI RadioButtons 控件,則間距、邊界和方向已經優化。
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 Apis:RadioButtons 類別、SelectedItem 屬性、SelectedIndex 属性、SelectionChanged 事件
- 開啟 WinUI 2 畫廊應用程式,然後看看 RadioButton 的實際運作。 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 />