下拉式方塊和清單方塊

使用下拉式方塊 (也稱為下拉式清單) 來呈現使用者可以從中選取的項目清單。 下拉式方塊一開始為精簡狀態,展開可顯示可選取的項目清單。 清單方塊與下拉式方塊類似,但前者無法摺疊,也沒有精簡狀態。 您可以在本文結尾深入了解清單方塊。

關閉下拉式方塊後,它會顯示目前的選取項目,若沒有已選取的項目則是空的。 當使用者展開下拉式方塊時,它會顯示可選取的項目清單。

An image of a drop-down list in its compact state.

這是正確的控制項嗎?

  • 使用下拉式清單讓使用者從一組專案中選取單一值,這些值可以適當地以單行文字表示。
  • 使用清單或網格線檢視,而不是下拉式方塊來顯示包含多行文字或影像的專案。
  • 當專案少於五個專案時,請考慮使用 圓形按鈕 (如果只能選取一個專案) 或 核取方塊 (如果可以選取多個專案)。
  • 當您的應用程式流程中選取專案具有次要重要性時,請使用下拉式方塊。 如果大部分情況下,大部分使用者都建議使用預設選項,使用清單檢視顯示所有專案可能會比必要專案更注意這些選項。 您可以使用下拉式方塊來節省空間,並將干擾降至最低。

範例

精簡狀態下的組合方塊可以顯示標題。

Screenshot showing a drop-down list in its compact state.

雖然下拉式方塊會展開以支援較長的字串長度,但請避免難以讀取的過長字串。

Example of a drop-down list with long text string

如果下拉式方塊中的集合夠長,捲軸就會出現容納它。 以邏輯方式將專案分組在清單中。

Example of a scroll bar in a drop-down list

建議

  • 將下拉式方塊專案的文字內容限制為單行。
  • 以最邏輯順序排序下拉式方塊中的專案。 將相關選項分組在一起,並將最常見的選項放在最上方。 依字母順序排序名稱、數位順序的數位,以及時間順序的日期。

清單方塊

清單方塊可讓使用者從集合中選擇單一專案或多個專案。 清單方塊類似於下拉式清單,不同之處在於清單方塊一律為開啟,清單方塊沒有精簡 (非展開) 狀態。 如果清單中沒有顯示所有項目的空間,則可以捲軸清單中的專案。

清單方塊是否為正確的控制項?

  • 當清單中的專案足以醒目顯示,以及當有足夠的螢幕實際空間時,清單方塊就很有用,以顯示完整清單。
  • 清單方塊應該讓使用者注意重要選擇中的完整替代方案集。 相反地,下拉式清單一開始會吸引使用者對選取專案的注意。
  • 若出現以下情況,請避免使用清單方塊:
    • 清單中的項目數量非常少。 一律具有相同 2 個選項的單選清單方塊可能會更能顯示為圓形按鈕。 在清單中有 3 或 4 個靜態專案時,也請考慮使用圓形按鈕。
    • 清單方塊是單選,而且一律有相同的 2 個選項,其中一個選項可以隱含為非另一個選項,例如「開啟」和「關閉」。使用單一核取方塊或切換開關。
    • 項目數量非常龐大。 長清單的較佳選擇是方格檢視和清單檢視。 對於很長的分組資料清單,偏好使用語意式縮放。
    • 項目是連續的數值。 如果是這種情況,請考慮使用滑桿
    • 選擇項目在應用程式流程中是次要的,或者在大多數情況下建議大多數使用者使用預設選項。 請改用下拉式清單。

清單方塊的建議

  • 清單方塊中的理想專案範圍是 3 到 9。
  • 清單方塊在專案可以動態變化時運作良好。
  • 可能的話,請設定清單方塊的大小,使其專案清單不需要進行瀏覽或捲動。
  • 確認清單方塊的目的,以及目前選取的專案是否清楚。
  • 保留觸控回饋的視覺效果和動畫,以及選取的項目狀態。
  • 將清單方塊項的文字內容限制為一行。 如果項目是視覺效果,您可以自訂大小。 如果專案包含多行文字或影像,請改用網格線檢視或列表檢視。
  • 除非您的品牌指導方針指示您使用其他字型,否則使用預設字型。
  • 請勿使用清單方塊來執行命令,或動態顯示或隱藏其他控制件。

UWP 和 WinUI 2

重要

本文中的資訊和範例針對使用 Windows App SDKWinUI 3 的應用程式進行了最佳化,但通常適用於使用 WinUI 2 的 UWP 應用程式。 如需平台特定資訊和範例,請參閱 UWP API 參考。

本節包含您在 UWP 或 WinUI 2 應用程式中使用控制項所需的資訊。

此控制項的 API 位在 Windows.UI.Xaml.Controls 命名空間中。

Windows UI 程式庫 2.2 或更新版本中有這個控制項使用圓角的新範本。 如需詳細資訊,請參閱圓角半徑

建立下拉式方塊

WinUI 3 資源庫應用程式包含大多數 WinUI 3 控制項和功能的互動式範例。 從 Microsoft Store 取得應用程式,或在 GitHub 上取得原始程式碼

直接將物件新增至 Items集合,或將 ItemsSource 屬性設為資料來源,即可填入下拉式方塊。 新增至 ComboBox 的項目會包裝在 ComboBoxItem 容器中。

以下是在 XAML 中新增項目的簡單下拉式方塊。

<ComboBox Header="Colors" PlaceholderText="Pick a color" Width="200">
    <x:String>Blue</x:String>
    <x:String>Green</x:String>
    <x:String>Red</x:String>
    <x:String>Yellow</x:String>
</ComboBox>

下列範例示範如何將下拉式方塊繫結至 FontFamily 物件集合。

<ComboBox x:Name="FontsCombo" Header="Fonts" Height="44" Width="296"
          ItemsSource="{x:Bind fonts}" DisplayMemberPath="Source"/>
ObservableCollection<FontFamily> fonts = new ObservableCollection<FontFamily>()
{
    fonts.Add(new FontFamily("Arial"));
    fonts.Add(new FontFamily("Courier New"));
    fonts.Add(new FontFamily("Times New Roman"));
};

項目選取

如同 ListView 和 GridView,ComboBox 衍生自選取器,因此您可以用相同的標準方式取得使用者的選取項目。

您可以使用 SelectedItem 屬性來取得或設定下拉式方塊的已選取項目,以及使用 SelectedIndex 屬性來取得或設定所選項目的索引。

若要在選取的資料項目上取得特定屬性的值,您可以使用 SelectedValue 屬性。 在此情況下,設定 SelectedValuePath 來指定要從所選項目上的哪個屬性取得此值。

提示

如果您設定 SelectedItem 或 SelectedIndex 來表示預設選取項目,如果在填入下拉式方塊 Items 集合前設定此屬性,就會發生例外狀況。 除非您在 XAML 中定義您的 Items,否則最好要處理下拉式方塊 Loaded 事件,並在 Loaded 事件處理常式中設定 SelectedItem 或 SelectedIndex。

您可以在 XAML 中繫結至這些屬性,或處理 SelectionChanged事件來回應選取項目變更。

在事件處理常式程式碼中,您可以從 SelectionChangedEventArgs.AddedItems 屬性取得所選的項目。 您可以從 SelectionChangedEventArgs.RemovedItems 屬性取得先前選取的項目 (如果有的話)。 AddedItems 和 RemovedItems 集合各自只包含 1 個項目,因為下拉式方塊並不支援多個選取項目。

這個範例示範如何處理 SelectionChanged 事件,以及如何繫結至選取的項目。

<StackPanel>
    <ComboBox x:Name="colorComboBox" Width="200"
              Header="Colors" PlaceholderText="Pick a color"
              SelectionChanged="ColorComboBox_SelectionChanged">
        <x:String>Blue</x:String>
        <x:String>Green</x:String>
        <x:String>Red</x:String>
        <x:String>Yellow</x:String>
    </ComboBox>

    <Rectangle x:Name="colorRectangle" Height="30" Width="100"
               Margin="0,8,0,0" HorizontalAlignment="Left"/>

    <TextBlock Text="{x:Bind colorComboBox.SelectedIndex, Mode=OneWay}"/>
    <TextBlock Text="{x:Bind colorComboBox.SelectedItem, Mode=OneWay}"/>
</StackPanel>
private void ColorComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    string colorName = e.AddedItems[0].ToString();
    Color color;
    switch (colorName)
    {
        case "Yellow":
            color = Colors.Yellow;
            break;
        case "Green":
            color = Colors.Green;
            break;
        case "Blue":
            color = Colors.Blue;
            break;
        case "Red":
            color = Colors.Red;
            break;
    }
    colorRectangle.Fill = new SolidColorBrush(color);
}

SelectionChanged 和鍵盤瀏覽

根據預設,當使用者對清單中的項目按一下、點選或按 Enter 鍵來認可其選取項目時,就會發生 SelectionChanged 事件,且下拉式方塊會關閉。 當使用者使用鍵盤方向鍵瀏覽開啟的下拉式方塊清單時,選取項目不會變更。

若要製作一個在使用者使用方向鍵尋覽開啟的清單時能「即時更新」的下拉式方塊 (例如字型選取下拉式清單),請將 SelectionChangedTrigger 設定為 Always。 當焦點變更為已開啟清單中的另一個項目時,這會導致 SelectionChanged 事件發生。

選取的項目行為變更

在 Windows 10 版本 1809 (SDK 17763) 或更新版本中,所選項目的行為會更新以支援可編輯的下拉式方塊。

在 SDK 17763 以前,SelectedItem 屬性的值 (因此 SelectedValue 和 SelectedIndex) 必須在下拉式方塊的 Items 集合中。 使用上述範例,設定 colorComboBox.SelectedItem = "Pink" 會導致:

  • SelectedItem = null
  • SelectedValue = null
  • SelectedIndex = -1

在 SDK 17763 和更新版本中,SelectedItem 屬性的值 (因此 SelectedValue 和 SelectedIndex) 不一定要在下拉式方塊的 Items 集合中。 使用上述範例,設定 colorComboBox.SelectedItem = "Pink" 會導致:

  • SelectedItem = Pink
  • SelectedValue = Pink
  • SelectedIndex = -1

組合方塊自動支援在其集合內搜尋 當使用者在實體鍵盤上輸入字元,同時將焦點放在開啟或關閉的下拉式方塊上時,會將符合使用者字串的候選專案帶入檢視中。 在瀏覽長清單時,這項功能特別有用。 例如,與包含狀態清單的下拉式清單進行互動時,使用者可以按 "w" 鍵來顯示 "Washington 以供快速選取。 文字搜尋不區分大小寫。

您可以將 IsTextSearchEnabled 屬性設定為 false,以停用這項功能。

讓下拉式方塊可進行編輯

重要

這項功能需要 Windows 10 版本 1809 (SDK 17763) 或更新版本。

根據預設,下拉式方塊可讓使用者從預先定義的選項清單中選取。 不過,有時候清單只包含一部分的有效值,而且使用者應該能夠輸入其他未列出的值。 若要支援這項功能,您可以讓下拉式方塊可進行編輯。

若要讓下拉式方塊可進行編輯,請將 IsEditable 屬性設定為 true。 然後,處理 TextSubmitted 事件來處理使用者所輸入的值。

根據預設,當使用者認可自訂文字時,就會更新 SelectedItem 值。 在 TextSubmitted 事件引數中將 Handled設定為 true,即可覆寫此行為。 當事件標記為已處理時,下拉式方塊不會在事件之後採取進一步動作,並將維持編輯中狀態。 將不會更新 SelectedItem。

這個範例顯示簡單的可編輯下拉式方塊。 此清單包含簡單的字串,並使用使用者所輸入的任何值。

「最近使用的名稱」選擇器可讓使用者輸入自訂字串。 'RecentlyUsedNames' 清單包含可供使用者選擇的一些值,但使用者也可以新增自訂值。 'CurrentName' 屬性表示目前輸入的名稱。

<ComboBox IsEditable="true"
          ItemsSource="{x:Bind RecentlyUsedNames}"
          SelectedItem="{x:Bind CurrentName, Mode=TwoWay}"/>

提交的文字

您可以處理 TextSubmitted 事件,以處理使用者所輸入的值。 在事件處理常式中,您通常會驗證使用者所輸入的值是否有效,然後在您的應用程式中使用此值。 視情況而定,您也可以將此值新增至下拉式方塊的選項清單中,以供未來使用。

符合下列條件時,就會發生 TextSubmitted 事件:

  • IsEditable 屬性為 true
  • 使用者在下拉式方塊清單中輸入不符合現有項目的文字
  • 使用者按 Enter 鍵,或從下拉式方塊移出焦點。

如果使用者輸入文字,然後向上或向下巡覽清單,則不會發生 TextSubmitted 事件。

範例 - 驗證輸入並在本機使用

在此範例中,字型大小選擇器包含一組對應至字型大小坡形的值,但使用者可以輸入不在清單中的字型大小。

當使用者新增不在清單中的值時,字型大小會更新,但此值不會新增至字型大小清單。

如果新輸入的值無效,您可使用 SelectedValue,將 Text 屬性還原為最後一個已知良好的值。

<ComboBox x:Name="fontSizeComboBox"
          IsEditable="true"
          ItemsSource="{x:Bind ListOfFontSizes}"
          TextSubmitted="FontSizeComboBox_TextSubmitted"/>
private void FontSizeComboBox_TextSubmitted(ComboBox sender, ComboBoxTextSubmittedEventArgs e)
{
    if (byte.TryParse(e.Text, out double newValue))
    {
        // Update the app's font size.
        _fontSize = newValue;
    }
    else
    {
        // If the item is invalid, reject it and revert the text.
        // Mark the event as handled so the framework doesn't update the selected item.
        sender.Text = sender.SelectedValue.ToString();
        e.Handled = true;
    }
}

範例 - 驗證輸入並新增至清單

在此,「最愛色彩選擇器」包含最常見的最愛色彩 (紅色、藍色、綠色、橘色),但使用者可以輸入不在清單中的最愛色彩。 當使用者新增有效的色彩 (例如粉紅色) 時,新輸入的色彩會新增到清單並設為有效的「最愛色彩」。

<ComboBox x:Name="favoriteColorComboBox"
          IsEditable="true"
          ItemsSource="{x:Bind ListOfColors}"
          TextSubmitted="FavoriteColorComboBox_TextSubmitted"/>
private void FavoriteColorComboBox_TextSubmitted(ComboBox sender, ComboBoxTextSubmittedEventArgs e)
{
    if (IsValid(e.Text))
    {
        FavoriteColor newColor = new FavoriteColor()
        {
            ColorName = e.Text,
            Color = ColorFromStringConverter(e.Text)
        }
        ListOfColors.Add(newColor);
    }
    else
    {
        // If the item is invalid, reject it but do not revert the text.
        // Mark the event as handled so the framework doesn't update the selected item.
        e.Handled = true;
    }
}

bool IsValid(string Text)
{
    // Validate that the string is: not empty; a color.
}

取得範例程式碼