콤보 상자 및 목록 상자

콤보 상자(드롭다운 목록이라고도 함)를 사용하여 사용자가 선택할 수 있는 항목 목록을 표시할 수 있습니다. 콤보 상자는 압축 상태에서 시작하여 선택 가능한 항목 목록을 표시하도록 확장됩니다. 목록 상자는 콤보 상자와 비슷하지만 축소할 수 없거나 압축 상태가 아닙니다. 이 문서 끝부분에서 목록 상자에 대해 자세히 알아볼 수 있습니다.

콤보 상자를 닫으면 콤보 상자는 현재 선택한 항목을 표시하거나 선택된 항목이 없는 경우 비어 있습니다. 사용자가 콤보 상자를 확장하면 콤보 상자는 선택 가능한 항목 목록을 표시합니다.

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

올바른 컨트롤인가요?

  • 드롭다운 목록을 사용하여 사용자가 한 줄짜리 문장으로 구성된 텍스트로 적절하게 나타낼 수 있는 항목 세트에서 단일 값을 선택할 수 있습니다.
  • 콤보 상자 대신 목록 또는 그리드 뷰를 사용하여 여러 줄의 텍스트 또는 이미지가 포함된 항목을 표시합니다.
  • 항목이 5개 미만인 경우, 라디오 버튼 (하나의 항목만 선택할 수 있는 경우) 또는 체크 박스 (여러 항목을 선택할 수 있는 경우)를 선택하는 것이 좋습니다.
  • 선택 항목이 앱 흐름에서 부차적인 경우 콤보 상자를 사용합니다. 대부분의 상황에서 사용자 대부분에게 기본 옵션을 권장한다면, 목록 보기를 사용하여 모든 항목을 표시하면 필요한 것보다 옵션에 더 많은 관심을 가져올 수 있습니다. 콤보 상자를 사용하여 공간을 절약하고 방해를 최소화할 수 있습니다.

예제

헤더를 표시하는 압축 상태의 콤보 상자입니다.

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

Important

이 문서의 정보 및 예제는 Windows 앱 SDKWinUI 3를 사용하는 앱에 최적화되어 있지만 통상적으로 WinUI 2를 사용하는 UWP 앱에도 적용할 수 있습니다. 플랫폼별 정보 및 예제는 UWP API 참조를 확인하세요.

이 섹션에는 UWP 또는 WinUI 2 앱에서 컨트롤을 사용하는 데 필요한 정보가 있습니다.

이 컨트롤용 API는 Windows.UI.Xaml.Controls 네임스페이스에 있습니다.

Windows UI Library 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를 설정하는 경우 콤보 상자 항목 컬렉션이 채워지기 전에 속성이 설정되면 예외가 발생합니다. XAML로 항목을 정의하지 않는 이상, 콤보 상자 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 이벤트가 발생하고, 콤보 상자가 닫힙니다. 사용자가 키보드의 화살표 키를 사용하여 열려 있는 콤보 상자 목록을 탐색할 때 선택 항목이 변경되지 않습니다.

사용자가 화살표 키를 사용하여 열려 있는 목록(예: 글꼴 선택 드롭다운)을 탐색하는 동안 "실시간으로 업데이트되는" 콤보 상자를 만들려면 SelectionChangedTriggerAlways로 설정합니다. 그러면 열려 있는 목록의 다른 항목으로 포커스가 변경될 때 SelectionChanged 이벤트가 발생합니다.

선택한 항목의 동작 변경

Windows 10 버전 1809(17763 SDK) 이상에서는 편집 가능한 콤보 상자를 지원하도록 선택한 항목의 동작이 업데이트됩니다.

SDK 17763 이전 버전에서는 SelectedItem 속성(및 따라서 SelectedValue 및 SelectedIndex)의 값이 반드시 콤보 상자의 항목 컬렉션에 있어야 했습니다. 이전 예제를 사용하여 colorComboBox.SelectedItem = "Pink"로 설정하면 다음과 같은 결과를 얻게 됩니다.

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

SDK 17763 이상 버전에서는 SelectedItem 속성(및 따라서 SelectedValue 및 SelectedIndex)의 값이 콤보 상자의 항목 컬렉션에 있지 않아도 됩니다. 이전 예제를 사용하여 colorComboBox.SelectedItem = "Pink"로 설정하면 다음과 같은 결과를 얻게 됩니다.

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

콤보 상자는 컬렉션 내에서 검색을 자동으로 지원합니다. 열려 있거나 닫힌 콤보 상자에 포커스가 있는 동안 사용자가 실제 키보드에 문자를 입력하면, 사용자의 문자열과 일치하는 후보가 표시됩니다. 이 기능은 긴 목록을 탐색할 때 특히 유용합니다. 예를 들어 상태 목록이 포함된 드롭다운을 조작할 때 사용자는 빠른 선택을 위해 "w" 키를 눌러 "워싱턴"을 표시할 수 있습니다. 텍스트 검색은 대/소문자를 구분하지 않습니다.

IsTextSearchEnabled 속성을 false로 설정하여 이 기능을 해제할 수 있습니다.

콤보 상자를 편집 가능하게 만들기

Important

이 기능을 사용하려면 Windows 10 버전 1809(17763 SDK) 이상이 필요합니다.

기본적으로 콤보 상자는 사용자가 미리 정의된 옵션 목록에서 선택할 수 있습니다. 그러나 목록에 유효한 값이 몇 개 없어서 사용자가 목록에 없는 다른 값을 입력할 수 있어야 하는 경우가 있습니다. 이 상황을 지원하려면 콤보 상자를 편집 가능하게 만들면 됩니다.

콤보 상자를 편집 가능하게 만들려면 IsEditable 속성을 true로 설정합니다. 그런 다음, 사용자가 입력한 값을 작업하는 TextSubmitted 이벤트를 처리합니다.

기본적으로 SelectedItem 값은 사용자가 사용자 지정 텍스트를 커밋할 때 업데이트됩니다. TextSubmitted 이벤트 인수에서 Handledtrue로 설정하여 이 동작을 재정의할 수 있습니다. 이벤트가 처리된 것으로 표시되면 콤보 상자는 이벤트 이후에 더 이상 작업을 수행하지 않으며 편집 중 상태를 유지합니다. 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.
}

샘플 코드 가져오기