英語で読む

次の方法で共有


コンボ ボックスとリスト ボックス

ユーザーが選択できる項目の一覧を提供するには、コンボ ボックス (ドロップダウン リストとも呼ばれる) を使用します。 コンボ ボックスは、最初はコンパクトな状態で、展開すると選択可能な項目の一覧が表示されます。 リスト ボックスはコンボ ボックスに似ていますが、折りたたむことができず、コンパクトな状態がありません。 リスト ボックスの詳細については、この記事の最後で詳細を確認できます。

コンボ ボックスを閉じると、現在の選択が表示されるか、選択された項目がない場合は空です。 ユーザーがコンボ ボックスを展開すると、選択可能な項目の一覧が表示されます。

コンパクトな状態のドロップダウン リストの画像。

これは適切なコントロールですか?

  • ドロップダウン リストを使用すると、ユーザーは 1 行のテキストで適切に表現できる項目のセットから 1 つの値を選択できます。
  • 複数行のテキストまたは画像を含む項目を表示するには、コンボ ボックスではなく、リスト ビューまたはグリッド ビューを使用します。
  • 項目が 5 個未満の場合は、ラジオ ボタン (1 つの項目しか選択できない場合) またはチェック ボックス (複数の項目を選択できる場合) の使用を検討してください。
  • 選択項目がアプリのフローで二次的に重要な場合は、コンボ ボックスを使用します。 ほとんどの状況でほとんどのユーザーに既定のオプションが推奨されている場合、リスト ビューを使用してすべてのアイテムを表示すると、必要以上にオプションに注意が向く可能性があります。 コンボ ボックスを使用すると、領域を節約し、注意散漫を最小限に抑えることができます。

コンパクトな状態のコンボ ボックスではヘッダーを表示できます。

コンパクトな状態のドロップダウン リストを示すスクリーンショット。

コンボ ボックスは、長い文字列の長さを表示するために拡張できますが、読みにくく長すぎる文字列は避けてください。

長いテキスト文字列を含むドロップダウン リストの例

コンボ ボックス内のコレクションが十分な長さである場合は、それに対応するようにスクロール バーが表示されます。 リスト内の項目を論理的にグループ化します。

ドロップダウン リストのスクロール バーの例

推奨事項

  • コンボ ボックス項目のテキスト コンテンツを 1 行に制限します。
  • コンボ ボックス内の項目を最も論理的な順序で並べ替えます。 関連するオプションをグループ化し、最も一般的なオプションを上部に配置します。 名前をアルファベット順、数値順に並べ替え、日付を時系列で並べ替えます。

リスト ボックス

リスト ボックスを使用すると、ユーザーはコレクションから 1 つの項目または複数の項目を選択できます。 リスト ボックスはドロップダウン リストに似ていますが、リスト ボックスは常に開いています。リスト ボックスのコンパクトな (展開されていない) 状態はありません。 すべてを表示するスペースがない場合は、リスト内の項目をスクロールできます。

リスト ボックスは適切なコントロールですか?

  • リスト ボックスは、リスト内の項目が目立つように表示するのに重要な場合や、完全なリストを表示するのに十分な画面スペースがある場合に役立ちます。
  • リスト ボックスを使用すると、ユーザーは、重要な選択肢の完全な一式に注意を向けることができます。 これに対し、ドロップダウン リストを使用すると、ユーザーは、最初に選択した項目に注意が向きます。
  • 次の場合は、リスト ボックスを使用しないでください。
    • リストの項目の数が非常に少ない。 常に同じ 2 つのオプションを持つ単一選択リスト ボックスは、ラジオ ボタンとして表示することをお勧めします。 また、リストに 3 つまたは 4 つの静的項目がある場合は、ラジオ ボタンの使用も検討してください。
    • リスト ボックスが単一選択であり、オプションが常に同じ 2 項目で、その一方が他方の否定を意味している場合 ("オン" と "オフ" など)。このような場合は、単一のチェック ボックスまたは切り替えスイッチを使用してください。
    • 非常に多くの項目がある。 長いリストの場合は、グリッド ビューとリスト ビューを選択することをお勧めします。 グループ化されたデータの非常に長いリストの場合は、セマンティック ズームが推奨されます。
    • 項目が連続した数値である。 その場合は、スライダーの使用を検討してください。
    • 選択項目は、アプリのフローにおいて二次的な重要性を持っているか、ほとんどの状況でほとんどのユーザーに対して既定のオプションが推奨されます。 代わりにドロップダウン リストを使用してください。

リスト ボックスのおすすめ

  • リスト ボックス内のアイテムの理想的な範囲は 3 ~ 9 です。
  • リスト ボックスは、項目が動的に変化する場合に適切に機能します。
  • 可能であれば、リスト ボックスのサイズを設定して、項目のリストをパンまたはスクロールする必要がないようにします。
  • リスト ボックスの目的と、現在選択されている項目がクリアされていることを確認します。
  • タッチ フィードバックと、選択した項目の状態の視覚効果とアニメーションを予約します。
  • リスト ボックス項目のテキスト コンテンツを 1 行に制限します。 項目がビジュアルの場合は、サイズをカスタマイズできます。 項目に複数行のテキストまたは画像が含まれている場合は、代わりにグリッド ビューまたはリスト ビューを使用します。
  • ブランドのガイドラインで別のフォントを使用することが示されていない限り、既定のフォントを使用します。
  • リスト ボックスを使用してコマンドを実行したり、他のコントロールを動的に表示または非表示にしたりしないでください。

UWP と WinUI 2

重要

この記事の情報と例は、Windows アプリ SDKWinUI 3 を使用するアプリ向けに最適化されていますが、一般に WinUI 2 を使用する UWP アプリに適用されます。 プラットフォーム固有の情報と例については、UWP API リファレンスを参照してください。

このセクションには、UWP または WinUI 2 アプリでコントロールを使用するために必要な情報が含まれています。

このコントロールの API は Windows.UI.Xaml.Controls 名前空間に存在します。

WinUI 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 は Selector から派生するため、標準と同じ方法でユーザーの選択を取得できます。

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 とキーボードのナビゲーション

既定では、SelectionChanged イベントは、ユーザーが一覧にある項目を対象にクリック、タップ、または Enter キーを押すことで選択を確定し、コンボ ボックスが閉じたときに発生します。 開いているコンボ ボックスの一覧をユーザーがキーボードの方向キーを使って移動しても、選択は変更されません。

開いている一覧をユーザーが方向キーを押して移動している間に "ライブ更新" されるコンボ ボックスを作成するには (フォント選択ドロップダウン リストなど)、SelectionChangedTriggerAlways に設定します。 これにより、開いている一覧にある別の項目にフォーカスが変更されたときに、SelectionChanged イベントが発生します。

選択された項目の動作の変更

Windows 10 Version 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 Version 1809 (SDK 17763) 以降が必要です。

既定では、コンボ ボックスを使用すると、ユーザーは事前に定義されたオプションの一覧から選択できます。 ただし、一覧に有効な値のサブセットのみが含まれていて、一覧にないその他の値をユーザーが入力できる場合があります。 これをサポートするために、コンボ ボックスを編集可能にすることができます。

コンボ ボックスを編集可能にするには、IsEditable プロパティを true に設定します。 次に TextSubmitted イベントを処理して、ユーザーが入力した値を処理します。

既定では、ユーザーがカスタム テキストを確定したときに、SelectedItem 値が更新されます。 TextSubmitted イベント引数で Handledtrue に設定することで、この動作をオーバーライドできます。 イベントが処理済みとしてマークされると、コンボ ボックスによるイベント後の操作はそれ以上実行されず、コンボ ボックスは編集中の状態のままとなります。 SelectedItem は更新されません。

この例では、シンプルな編集可能コンボ ボックスを示しています。 一覧にはシンプルな文字列が含まれていて、ユーザーが入力した値は入力したとおりに使用されます。

"recently used names" (最近使った名前) のセレクターでは、ユーザーはカスタム文字列を入力できます。 '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;
    }
}

サンプル - 入力を検証して一覧に追加する

ここでは、"favorite color セレクター" には、好きな色として最も一般的な色 (赤、青、緑、オレンジ色) が含まれていますが、ユーザーは一覧にない好きな色を入力できます。 ユーザーが有効な色 (ピンクなど) を追加すると、その新しく入力された色が一覧に追加され、アクティブな "favorite color" (好きな色) として設定されます。

<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.
}

サンプル コードの入手