목록 보기 및 그리드 보기

응용 프로그램 대부분에서 이미지 갤러리 또는 이메일 메시지 세트와 같은 데이터 세트를 조작하고 표시합니다. XAML UI 프레임워크는 ListView와 GridView 컨트롤을 제공하여 앱에서 데이터를 쉽게 표시하고 조작할 수 있게 합니다.

참고 항목

ListView 및 GridView 모두 ListViewBase 클래스에서 파생되므로 동일한 기능을 갖지만 데이터를 다르게 표시합니다. 다른 언급이 없는 한, 이 문서에서는 list view에 대한 논의 사항이 ListView 및 GridView 컨트롤 모두에 적용됩니다. ListView 또는 ListViewItem과 같은 클래스를 참조할 수 있지만 그리드와 관련된 동일한 항목에 대해 List 접두사는 Grid로 바꿀 수 있습니다(GridView 또는 GridViewItem).

ListView 및 GridView 컨트롤은 컬렉션 작업 과정에 많은 이점을 제공합니다. 둘 다 사용자 지정이 용이한 데다 구현하기 쉽고 기본 UI, 상호 작용 및 스크롤 기능을 제공합니다. ListView 및 GridView는 기존 동적 데이터 소스 또는 XAML 자체에 혹은 코드 비하인드에 제공되는 하드 코딩된 데이터에 바인딩할 수 있습니다.

두 컨트롤 모두 다양한 시나리오에서 유연하게 사용할 수 있지만, 전반적으로 모든 항목이 동일한 기본 구조와 모양뿐만 아니라 동일한 상호 작용 동작을 갖는 컬렉션에서 가장 잘 작동합니다. 즉, 모두 클릭할 때(예: 링크를 열거나 찾아보기 위해) 동일한 작업을 수행해야 합니다.

ListView와 GridView 비교하기

ListView

ListView 컨트롤은 단일 열에 수직으로 누적된 데이터를 표시합니다. ListView는 텍스트를 중심으로 하는 항목과 위에서 아래로 읽어야 하는(예: 사전순 정렬) 컬렉션에 더 적합합니다. ListView의 일반적인 사용 사례로 메시지 목록과 검색 결과를 들 수 있습니다. 컬렉션을 여러 열 또는 테이블과 같은 형식으로 표시해야 하는 경우 ListView를 사용하면 됩니다. 대신 DataGrid 컨트롤을 사용하는 것이 좋습니다.

Screenshot of a list view of data that's grouped alphabetically.

GridView

GridVIew 컨트롤은 수직으로 스크롤할 수 있는 행과 열 형태로 항목 컬렉션을 보여줍니다. 데이터가 열 하나를 모두 채울 때까지 가로로 쌓이며, 이후 열의 다음 행으로 이어집니다. GridView는 이미지를 중심으로 하는 컬렉션 또는 옆으로 넘어가며 읽을 수 있거나 특정한 정렬 방식이 있지 않은 컬렉션에 더 적합합니다. GridView의 일반적인 사용 사례로 사진 또는 제품 갤러리를 들 수 있습니다.

Screenshot of a content library of photos displayed as a grid view.

어떤 컬렉션 컨트롤을 사용해야 하나요? ItemsRepeater와 비교

사용할 컨트롤을 결정하기 전에 컨트롤 타입 간의 차이점을 이해하는 것이 중요합니다.

ListView 및 GridView

다기능 컨트롤인 ListView 및 GridView 컨트롤은 별도의 설치나 구성이 필요 없이 바로 작동합니다. 사용자 지정이 필수는 아니나, 쉽게 할 수 있습니다. 각각에는 고유한 빌트인 UI와 UX가 있으며 거의 모든 타입의 컬렉션을 있는 그대로 표시하도록 설계되었습니다.

ItemsRepeater

ItemsRepeater 컨트롤 역시 컬렉션을 표시하는 데 사용되지만, 특정 UI 요구 사항에 적합한 사용자 지정 컨트롤을 만들기 위한 빌딩 블록으로 설계되었습니다. ListView 및 GridView와 동일한 빌트인 feature와 functionality를 갖고 있지 않으므로 필요한 feature나 상호작용을 구현해야 합니다. ListView 또는 GridView로는 만들 수 없는 사용자 지정 UI가 있거나 각 항목에 전혀 다른 동작을 요구하는 데이터 소스가 있는 경우 ItemsRepeater를 사용합니다.

ItemsRepeater에 대한 자세한 내용은 해당 지침API 문서화 페이지를 참조하세요.

UWP 및 WinUI 2

Important

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

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

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

최신 WinUI 2를 사용하여 모든 컨트롤에 적용되는 최신 스타일과 템플릿을 가져오는 것이 좋습니다.

list 보기 또는 grid 보기 만들기

WinUI 3 갤러리 앱을 열고 작동 중인 ListView 또는 GridView를 확인합니다.

WinUI 3 갤러리 앱에는 대부분의 WinUI 3 컨트롤, 특징, 기능의 대화형 예제가 포함되어 있습니다. Microsoft Store에서 앱을 다운로드하거나 GitHub에서 소스 코드를 가져오세요

ListView 및 GridView는 모두 ItemsControl 형식이므로 모든 형식의 항목 컬렉션을 포함할 수 있습니다. ListView 또는 GridView 컨트롤은 화면에 무언가를 표시하려면 해당 Items 컬렉션에 항목이 있어야 합니다. 뷰를 채우려면 컬렉션 에 직접 항목을 추가하거나 ItemsSource 속성을 데이터 소스로 설정하시면 됩니다.

주의

Items 또는 ItemsSource 속성을 사용하여 목록을 채울 수 있지만 두 속성을 동시에 사용할 수는 없습니다. ItemsSource 속성을 설정하고 XAML에 항목을 추가하면 추가된 항목이 무시됩니다. ItemsSource 속성을 설정하고 코드의 Items 컬렉션에 항목을 추가하면 예외가 throw됩니다.

이 문서의 예시 다수에서 단순성을 위해 Items 컬렉션을 직접 채웁니다. 그러나 온라인 데이터베이스의 책 목록과 같이, 목록 내 항목은 동적 소스에서 가져오는 것이 더 일반적입니다. 이를 위해 ItemSource 속성을 사용합니다.

ListView 또는 GridView에 항목 추가하기

XAML 또는 코드를 통해 ListView 또는 GridView의 Items 컬렉션에 항목을 추가하여 동일한 결과를 얻을 수 있습니다. 변경되지 않고 쉽게 정의되는 항목 수가 적은 경우 또는 런타임 시 코드에서 항목을 생성하는 경우 통상 XAML을 통해 항목을 추가합니다.

방법 1: Items 컬렉션에 항목 추가하기

  • 옵션 1: XAML을 통해 항목 추가하기

    <!-- No corresponding C# code is needed for this example. -->
    
    <ListView x:Name="Fruits">
    <x:String>Apricot</x:String>
    <x:String>Banana</x:String>
    <x:String>Cherry</x:String>
    <x:String>Orange</x:String>
    <x:String>Strawberry</x:String>
    </ListView>
    
  • 옵션 2: 코드를 통해 항목 추가하기

    <StackPanel Name="FruitsPanel"></StackPanel>
    
    // Create a new ListView and add content.
    ListView Fruits = new ListView();
    Fruits.Items.Add("Apricot");
    Fruits.Items.Add("Banana");
    Fruits.Items.Add("Cherry");
    Fruits.Items.Add("Orange");
    Fruits.Items.Add("Strawberry");
    
    // Add the ListView to a parent container in the visual tree (which you created in the corresponding XAML file).
    FruitsPanel.Children.Add(Fruits);
    

두 옵션 모두 다음과 같이 동일한 list view를 생성합니다.

Screenshot of a simple list view displaying a list of fruits.

방법 2: ItemsSource 속성을 설정하여 항목 추가하기

데이터베이스나 인터넷 등의 소스에서 데이터를 표시하는 데 통상 ListView 또는 GridView를 사용합니다. 데이터 소스에서 ListView 또는 GridView를 채우려면 ItemsSource 속성을 데이터 항목 컬렉션에 설정합니다. 다음 예제에 표시된 것처럼 ListView 또는 GridView가 사용자 지정 클래스 객체를 보유하게 되는 경우 이 방법이 더 적합합니다.

  • 옵션 1: 코드에서 ItemsSource 설정하기

    여기서는 ListView ItemsSource 속성이 코드에서 바로 컬렉션의 인스턴스로 설정됩니다.

    <StackPanel x:Name="ContactPanel"></StackPanel>
    
    // Class definition should be provided within the namespace being used, outside of any other classes.
    
    this.InitializeComponent();
    
    // Instead of adding hard coded items to an ObservableCollection as shown here,
    //the data could be pulled asynchronously from a database or the internet.
    ObservableCollection<Contact> Contacts = new ObservableCollection<Contact>();
    
    // You create Contact objects by providing a first name, last name, and company for the Contact constructor.
    // They are then added to the ObservableCollection Contacts.
    Contacts.Add(new Contact("John", "Doe", "Contoso, LTD."));
    Contacts.Add(new Contact("Jane", "Doe", "Fabrikam, Inc."));
    Contacts.Add(new Contact("Santa", "Claus", "Alpine Ski House"));
    
    // Create a new ListView (or GridView) for the UI, and add content by setting ItemsSource
    ListView ContactsLV = new ListView();
    ContactsLV.ItemsSource = Contacts;
    
    // Add the ListView to a parent container in the visual tree (which you created in the corresponding XAML file)
    ContactPanel.Children.Add(ContactsLV);
    
  • 옵션 2: XAML에서 ItemsSource 설정하기

    XAML에서 ItemsSource 속성을 컬렉션에 바인딩할 수도 있습니다. 여기서는, ItemsSource가 _contacts라고 하는 이 페이지의 프라이빗 데이터 컬렉션을 노출하는 Contacts라는 퍼블릭 속성에 바인딩됩니다.

    <ListView x:Name="ContactsLV" ItemsSource="{x:Bind Contacts}"/>
    
    // Provide a class definition within the namespace being used, outside of any other classes.
    // These two declarations belong outside the main page class.
    private ObservableCollection<Contact> _contacts = new ObservableCollection<Contact>();
    
    public ObservableCollection<Contact> Contacts
    {
        get { return this._contacts; }
    }
    
    // Define this method within your main page class.
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
    
        // Instead of hard coded items, the data could be pulled
        // asynchronously from a database or the internet.
        Contacts.Add(new Contact("John", "Doe", "Contoso, LTD."));
        Contacts.Add(new Contact("Jane", "Doe", "Fabrikam, Inc."));
        Contacts.Add(new Contact("Santa", "Claus", "Alpine Ski House"));
    }
    

다음 스크린샷과 같이 두 옵션 모두 동일한 list view를 생성합니다. (이 연습에 대해 데이터 템플릿이 정의되지 않았기 때문에 list view에는 각 항목의 문자열 표현이 표시됩니다.)

Screenshot displaying a simple list view with the ItemsSource property set.

Important

정의된 데이터 템플릿이 없는 경우, 사용자 지정 클래스 객체는 ToString 메서드가 정의된 경우에 한정해 해당 문자열 값을 사용하여 list view에만 표시됩니다.

다음 섹션에서는 ListView 또는 GridView 템플릿에서 단순 사용자 지정 클래스 항목을 시각적으로 표시하는 적절한 방법을 자세히 살펴봅니다.

데이터 바인딩에 대한 자세한 내용은 데이터 바인딩 개요를 참조하세요.

참고 항목

그룹화된 데이터를 list view에 표시해야 하는 경우 CollectionViewSource 클래스에 바인딩해야 합니다. CollectionViewSource는 XAML에서 컬렉션 클래스의 프록시 역할을 하며 그룹화 지원 사용을 지원합니다. 자세한 내용은 CollectionViewSource를 참조하세요.

데이터 템플릿으로 모양 사용자 지정하기

ListView 또는 GridView 컨트롤에서 데이터 템플릿을 사용하여 항목과 데이터를 시각화하는 방법을 정의할 수 있습니다. 기본적으로 데이터 항목은 바운딩된 데이터 개체의 문자열 표현으로 목록 보기에 표시됩니다. DisplayMemberPath를 해당 속성으로 설정하여 데이터 항목의 특정 속성에 대한 문자열 표현을 표시할 수 있습니다.

그러나 통상 데이터의 더 풍부한 프레젠테이션을 표시하고자 할 수 있습니다. list view 또는 grid view에서 항목이 표시되는 방법을 정확히 지정하려면 DataTemplate 클래스를 만듭니다. 개별 항목을 표시하는 데 사용되는 컨트롤의 레이아웃 및 모양을 DataTemplate의 XAML으로 정의합니다. 레이아웃의 컨트롤은 데이터 객체의 속성에 바인딩되거나 정의된 정적 콘텐츠를 인라인으로 갖고 있을 수 있습니다.

Important

DataTemplate에서 x:Bind 태그 확장을 사용하는 경우 데이터 템플릿에서 데이터 타입(x:DataType)을 지정해야 합니다.

단순 ListView 데이터 템플릿

이 예제의 데이터 항목은 간단한 문자열입니다. ListView 정의 내에 인라인으로 DataTemplete을 정의하여 문자열 왼쪽에 이미지를 추가하고 문자열을 청록색으로 표시합니다. 이는 메서드 1 하의 옵션 1을 사용하여 이전에 만든 것과 동일한 ListView 컨트롤입니다.

<!--No corresponding code is needed for this example.-->
<ListView x:Name="FruitsList">
                <ListView.ItemTemplate>
                    <DataTemplate x:DataType="x:String">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="47"/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <Image Source="Assets/placeholder.png" Width="32" Height="32"
                                HorizontalAlignment="Left" VerticalAlignment="Center"/>
                            <TextBlock Text="{x:Bind}" Foreground="Teal" FontSize="14"
                                Grid.Column="1" VerticalAlignment="Center"/>
                        </Grid>
                    </DataTemplate>
                </ListView.ItemTemplate>
                <x:String>Apricot</x:String>
                <x:String>Banana</x:String>
                <x:String>Cherry</x:String>
                <x:String>Orange</x:String>
                <x:String>Strawberry</x:String>
            </ListView>

단순 ListView 데이터 템플릿을 적용할 때 데이터 항목이 표시되는 방법은 다음과 같습니다.

Screenshot of list that's displayed after a simple ListView data template is applied.

사용자 지정 클래스 객체에 대한 ListView 데이터 템플릿

다음 예제에서 데이터 항목은 Contact 객체입니다. ListView 정의 내에 인라인으로 DataTemplate을 정의하여 Contact 이름 및 회사 왼쪽에 연락처 이미지를 추가합니다. 앞에서 보여준 것처럼, 이 ListView 데이터 템플릿은 메서드 2 하의 옵션 2에서 만들어졌습니다.

<ListView x:Name="ContactsLV" ItemsSource="{x:Bind Contacts}">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="local:Contact">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*"/>
                    <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Image Grid.Column="0" Grid.RowSpan="2" Source="Assets/grey-placeholder.png" Width="32"
                    Height="32" HorizontalAlignment="Center" VerticalAlignment="Center"></Image>
                <TextBlock Grid.Column="1" Text="{x:Bind Name}" Margin="12,6,0,0"
                    Style="{ThemeResource BaseTextBlockStyle}"/>
                <TextBlock  Grid.Column="1" Grid.Row="1" Text="{x:Bind Company}" Margin="12,0,0,6"
                    Style="{ThemeResource BodyTextBlockStyle}"/>
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

사용자 지정 클래스 객체에 ListView 데이터 템플릿을 적용할 때 데이터 항목이 표시되는 방법은 다음과 같습니다.

Screenshot of a list that's displayed after a ListView data template for custom class objects is applied.

데이터 템플릿은 ListView의 모양을 정의하는 기본적인 방법입니다. 또한 목록에 항목이 많은 경우, 성능에 큰 영향을 미칠 수 있습니다.

이전 코드에서 보여드린 것처럼, 데이터 템플릿을 ListView 또는 GridView 정의 내에서 인라인으로 정의할 수도 있고, Resources 섹션에서 별도로 정의할 수도 있습니다. ListView 또는 GridView 정의 외부에서 정의한 경우, DataTemplate에 x:Key 속성을 부여하고 해당 키를 사용하여 DataTemplate을 ListView 또는 GridView의 ItemTemplate 속성에 할당해야 합니다.

데이터 템플릿 및 항목 컨테이너를 사용하여 목록이나 그리드의 항목 모양을 정의하는 방법에 대한 자세한 내용과 예제는 항목 컨테이너 및 템플릿을 참조하세요.

항목의 레이아웃 변경

ListView 또는 GridView 컨트롤에 항목을 추가하면 컨트롤이 항목 컨테이너의 각 항목을 자동으로 줄 바꿈한 후 모든 항목 컨테이너를 배치합니다. 이러한 항목 컨테이너를 배치하는 방법은 컨트롤의 ItemsPanel 속성에 따라 달라집니다.

  • 기본적으로 ListView는 다음과 같이 수직으로 목록을 생성하는 ItemsStackPanel을 사용합니다.

    Screenshot of a simple list view displaying a vertical list of items.

  • GridView는 다음과 같이 가로로 항목을 추가하고 세로로 줄 바꿈 및 스크롤하는 ItemsWrapGrid를 사용합니다.

    Screenshot of a simple grid view displaying a horizontal list of items.

항목 패널에서 속성을 조정하여 항목의 레이아웃을 수정하거나 기본 패널을 다른 패널로 바꿀 수 있습니다.

참고 항목

ItemsPanel을 변경하는 경우, 가상화를 사용하지 않도록 설정하지 마십시오. ItemsStackPanel과 ItemsWrapGrid는 모두 가상화를 지원하므로 이 클래스들은 안전하게 사용할 수 있습니다. 다른 패널을 사용하는 경우, 가상화 사용을 비활성화하고 list view의 성능을 저하시킬 수 있습니다. 자세한 내용은 성능 아래의 list view 문서를 참조하세요.

이 예제에서는 ItemsStackPanel의 Orientation 속성을 변경하여 가로로 된 리스트에 항목 컨테이너를 ListView 컨트롤로 배치하는 방법을 보여줍니다.

list view는 기본적으로 수직으로 스크롤되므로 list view의 내부 ScrollViewerdptj 일부 속성을 조정해야 가로로 스크롤할 수 있습니다.

  • ScrollViewer.HorizontalScrollMode를 Enabled 또는 Auto하나로 변경합니다.
  • ScrollViewer.HorizontalScrollBarVisibility를 Auto로 변경해야 합니다.
  • ScrollViewer.VerticalScrollMode를 Disable로 변경해야 합니다.
  • ScrollViewer.VerticalScrollBarVisibility를 Hidden으로 변경해야 합니다.

Important

다음 예제는 width 제한이 없는 list view를 보여주므로, 가로 스크롤 막대가 표시되지 않습니다. 이 코드를 실행하면 ListView에서 스크롤 막대가 보이도록 설정할 Width="180" 수 있습니다.

<ListView Height="60"
          ScrollViewer.HorizontalScrollMode="Enabled"
          ScrollViewer.HorizontalScrollBarVisibility="Auto"
          ScrollViewer.VerticalScrollMode="Disabled"
          ScrollViewer.VerticalScrollBarVisibility="Hidden">
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <ItemsStackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
    <x:String>Apricot</x:String>
    <x:String>Banana</x:String>
    <x:String>Cherry</x:String>
    <x:String>Orange</x:String>
    <x:String>Strawberry</x:String>
</ListView>

목록이 표시되는 방법은 다음과 같습니다.

Screenshot of a horizontal list view.

다음 예제에서 ListView는 ItemsStackPanel 대신 ItemsWrapGrid를 사용하여 세로 줄 바꿈 list에 항목을 배치합니다.

Important

컨트롤이 강제로 컨테이너를 줄 바꿈하도록 list view의 height를 제한해야 합니다.

<ListView Height="100"
          ScrollViewer.HorizontalScrollMode="Enabled"
          ScrollViewer.HorizontalScrollBarVisibility="Auto"
          ScrollViewer.VerticalScrollMode="Disabled"
          ScrollViewer.VerticalScrollBarVisibility="Hidden">
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <ItemsWrapGrid/>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
    <x:String>Apricot</x:String>
    <x:String>Banana</x:String>
    <x:String>Cherry</x:String>
    <x:String>Orange</x:String>
    <x:String>Strawberry</x:String>
</ListView>

목록이 표시되는 방법은 다음과 같습니다.

Screenshot of a list view with a grid layout.

list view에서 그룹화된 데이터를 표시하는 경우, ItemsPanel은 개별 항목이 배치되는 방식이 아니라 항목 그룹을 배치하는 방법을 결정합니다. 예를 들어 이전에 표시된 가로 ItemsStackPanel을 사용하여 그룹화된 데이터를 표시하는 경우 그룹은 가로로 정렬되지만 각 그룹의 항목은 다음과 같이 세로로 쌓입니다.

Screenshot of a grouped horizontal list view..

항목 선택 및 상호 작용

사용자가 list view와 상호 작용할 수 있도록 하는 방법 여러 개 중에서 선택할 수 있습니다. 기본적으로 사용자는 단일 항목을 선택할 수 있습니다. SelectionMode 속성을 변경하여 다중 선택을 활성화하거나 선택을 비활성화할 수 있습니다. IsItemClickEnabled 속성을 설정하여 사용자가 (예를 들어 단추와 같은) 항목을 선택하는 대신 클릭을 하여 액션을 호출할 수 있습니다.

참고 항목

ListView 및 GridView 모두 SelectionMode 속성에 대해 ListViewSelectionMode 열거형을 사용합니다. IsItemClickEnabled는 기본적으로 False로 설정되므로 클릭 모드 활성화를 설정해야 합니다.

이 표에서는 사용자가 list view와 상호 작용할 수 있는 방법과 상호 작용에 응답하는 방법을 보여줍니다.

상호 작용을 활성화하려면 다음을 수행합니다. 사용할 설정 이벤트를 처리합니다. 이 속성을 사용하여 선택한 항목을 가져옵니다.
상호 작용 없음 SelectionMode="None"
IsItemClickEnabled="False"
해당 없음 해당 없음
단일 선택 SelectionMode="Single"
IsItemClickEnabled="False"
SelectionChanged SelectedItem
SelectedIndex
다중 선택 SelectionMode="Multiple"
IsItemClickEnabled="False"
SelectionChanged SelectedItems
확장 선택 SelectionMode="Extended"
IsItemClickEnabled="False"
SelectionChanged SelectedItems
클릭 SelectionMode="None"
IsItemClickEnabled="True"
ItemClick 해당 없음

참고 항목

IsItemClickEnabled를 활성화하여 SelectionMode가 Single, Multiple, 또는 Extended로 설정된 상태에서 ItemClick 이벤트를 발생시킬 수 있습니다. 이렇게 하면 ItemClick 이벤트가 먼저 발생되고, 이후 SelectionChanged 이벤트가 발생합니다. 경우에 따라(예: ItemClick 이벤트 처리기의 다른 페이지로 이동하는 경우) SelectionChanged 이벤트가 발생하지 않고 항목이 선택되지 않습니다.

다음과 같이 XAML 또는 코드에서 해당 속성을 설정할 수 있습니다.

<ListView x:Name="myListView" SelectionMode="Multiple"/>

<GridView x:Name="myGridView" SelectionMode="None" IsItemClickEnabled="True"/>
myListView.SelectionMode = ListViewSelectionMode.Multiple;

myGridView.SelectionMode = ListViewSelectionMode.None;
myGridView.IsItemClickEnabled = true;

읽기 전용

SelectionMode 속성을 ListViewSelectionMode.None 으로 설정하여 항목 선택을 비활성화할 수 있습니다. 이렇게 하면 컨트롤이 읽기 전용 모드가 되므로 데이터를 표시하는 데 사용되고 상호 작용에는 사용되지 않습니다. 즉, 항목 선택을 비활성화하지만 컨트롤 자체가 비활성화되는 것은 아닙니다.

단일 선택

이 표에서는 SelectionMode가 Single로 설정된 경우의 키보드, 마우스 및 터치 조작에 대해 설명합니다.

보조 키 상호 작용
None
  • 사용자는 스페이스바, 마우스 클릭 또는 탭을 사용하여 단일 항목을 선택할 수 있습니다.
  • Ctrl
  • 사용자는 스페이스바, 마우스 클릭 또는 탭을 사용하여 단일 항목 선택을 취소할 수 있습니다.
  • 화살표 키를 사용하면 선택 영역과 관계없이 포커스를 이동할 수 있습니다.
  • SelectionMode가 Single이면 SelectedItem 속성에서 선택한 데이터 항목을 가져올 수 있습니다. SelectedIndex 속성을 사용하여 선택한 항목의 컬렉션에서 인덱스를 가져올 수 있습니다. 선택한 항목이 없으면 SelectedItem이 null 값이고 SelectedIndex는 -1입니다.

    Items 컬렉션에 없는 항목을 SelectedItem으로 설정하려고 하면 오퍼레이션이 무시되고 SelectedItem이 null 값이 됩니다. 그러나 SelectedIndex를 list의 항목 범위를 벗어난 인덱스로 설정하려고 하면 System.ArgumentException 예외가 발생합니다.

    다중 선택

    이 표에서는 SelectionMode가 Multiple로 설정된 경우의 키보드, 마우스 및 터치 조작에 대해 설명합니다.

    보조 키 상호 작용
    None
  • 사용자는 스페이스바, 마우스 클릭 또는 탭을 사용하여 여러 항목을 선택하여 포커스를 가진 항목을 선택할 수 있습니다.
  • 화살표 키를 사용하면 선택과 관계없이 포커스를 이동할 수 있습니다.
  • Shift
  • 사용자는 선택 영역의 첫 번째 항목을 클릭하거나 탭한 다음 선택 영역의 마지막 항목을 클릭하거나 탭하여 여러 항목을 연속으로 선택할 수 있습니다.
  • 화살표 키를 사용하면 Shift 키를 선택할 때 선택된 항목부터 시작하여 항목을 연속으로 선택할 수 있습니다.
  • 확장 선택

    이 표에서는 SelectionMode가 Extended로 설정된 경우의 키보드, 마우스 및 터치 조작에 대해 설명합니다.

    보조 키 상호 작용
    None
  • 동작은 Single 선택 영역과 동일합니다.
  • Ctrl
  • 사용자는 스페이스바, 마우스 클릭 또는 탭을 사용하여 여러 항목을 선택하여 포커스를 가진 항목을 선택할 수 있습니다.
  • 화살표 키를 사용하면 선택 영역과 관계없이 포커스를 이동할 수 있습니다.
  • Shift
  • 사용자는 선택 영역의 첫 번째 항목을 클릭하거나 탭한 다음 선택 영역의 마지막 항목을 클릭하거나 탭하여 여러 항목을 연속으로 선택할 수 있습니다.
  • 화살표 키를 사용하면 Shift 키를 선택할 때 선택된 항목부터 시작하여 항목을 연속으로 선택할 수 있습니다.
  • SelectionMode가 Multiple 또는 Extended이면 SelectedItems 속성에서 선택된 데이터 항목을 가져올 수 있습니다.

    SelectedIndex, SelectedItem 및 SelectedItems 속성이 동기화됩니다. 예를 들어 SelectedIndex를 -1로 설정하면 SelectedItem이 null 값으로 설정되고 SelectedItems가 비게 됩니다. SelectedItem을 null 값으로 설정하면 SelectedIndex가 -1로 설정되고 SelectedItems가 비게 됩니다.

    다중 선택 모드에서 SelectedItem은 우선 선택된 항목을 포함하고 Selectedindex는 우선 선택된 항목의 인덱스를 포함합니다.

    선택 변경 내용에 응답하기

    list view에서 선택 변경 내용에 응답하려면 SelectionChanged 이벤트를 처리합니다. 이벤트 처리기 코드에서는 SelectionChangedEventArgs.AddedItems 속성에서 선택 항목의 list를 가져올 수 있습니다. SelectionChangedEventsArgs.RemovedItems 속성에서 선택 취소한 항목을 가져올 수 있습니다. 사용자가 Shift 키를 누른 채 항목 범위를 선택하지 않는 한, AddedItems 및 RemovedItems 컬렉션에 항목은 하나밖에 포함되지 않습니다.

    다음 예제에서는 SelectionChanged 이벤트를 처리하고 다양한 Item 컬렉션에 액세스하는 방법을 보여 줍니다.

    <StackPanel HorizontalAlignment="Right">
        <ListView x:Name="listView1" SelectionMode="Multiple"
                  SelectionChanged="ListView1_SelectionChanged">
            <x:String>Apricot</x:String>
            <x:String>Banana</x:String>
            <x:String>Cherry</x:String>
            <x:String>Orange</x:String>
            <x:String>Strawberry</x:String>
        </ListView>
        <TextBlock x:Name="selectedItem"/>
        <TextBlock x:Name="selectedIndex"/>
        <TextBlock x:Name="selectedItemCount"/>
        <TextBlock x:Name="addedItems"/>
        <TextBlock x:Name="removedItems"/>
    </StackPanel>
    
    private void ListView1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (listView1.SelectedItem != null)
        {
            selectedItem.Text =
                "Selected item: " + listView1.SelectedItem.ToString();
        }
        else
        {
            selectedItem.Text =
                "Selected item: null";
        }
        selectedIndex.Text =
            "Selected index: " + listView1.SelectedIndex.ToString();
        selectedItemCount.Text =
            "Items selected: " + listView1.SelectedItems.Count.ToString();
        addedItems.Text =
            "Added: " + e.AddedItems.Count.ToString();
        removedItems.Text =
            "Removed: " + e.RemovedItems.Count.ToString();
    }
    

    클릭 모드

    사용자가 버튼 및 기타 항목을 선택하는 대신 클릭할 수 있도록 list view를 변경할 수 있습니다. 예를 들어 사용자가 list 또는 grid에 있는 항목을 클릭할 때 앱이 새 페이지를 여는 경우에 유용합니다.

    이 동작을 사용하도록 설정하려면:

    • SelectionMode를 None으로 설정합니다.
    • IsItemClickEnabled를 True로 설정합니다.
    • 사용자가 항목을 클릭할 때 항목을 수행하도록 ItemClick 이벤트를 처리합니다.

    클릭 가능한 항목이 있는 list view는 다음과 같습니다. ItemClick 이벤트 처리기의 코드는 앱에서 새 페이지를 엽니다.

    <ListView SelectionMode="None"
              IsItemClickEnabled="True"
              ItemClick="ListView1_ItemClick">
        <x:String>Page 1</x:String>
        <x:String>Page 2</x:String>
        <x:String>Page 3</x:String>
        <x:String>Page 4</x:String>
        <x:String>Page 5</x:String>
    </ListView>
    
    private void ListView1_ItemClick(object sender, ItemClickEventArgs e)
    {
        switch (e.ClickedItem.ToString())
        {
            case "Page 1":
                this.Frame.Navigate(typeof(Page1));
                break;
    
            case "Page 2":
                this.Frame.Navigate(typeof(Page2));
                break;
    
            case "Page 3":
                this.Frame.Navigate(typeof(Page3));
                break;
    
            case "Page 4":
                this.Frame.Navigate(typeof(Page4));
                break;
    
            case "Page 5":
                this.Frame.Navigate(typeof(Page5));
                break;
    
            default:
                break;
        }
    }
    

    프로그래밍 방식으로 항목 범위를 선택하기

    경우에 따라 프로그래밍 방식으로 ListView 항목 선택을 조작해야 할 수 있습니다. 예를 들어, Select all 버튼을 보여주어 사용자가 list에 있는 모든 항목을 선택할 수 있게 할 수 있습니다. 이 경우 SelectedItems 컬렉션에서 항목을 하나씩 추가하고 제거하는 것이 일반적으로 그리 효율적이지는 않습니다. 각 항목 변경으로 인해 SelectionChanged 이벤트가 발생하며, 인덱스 값을 사용하는 대신 항목으로 직접 작업하면 항목이 가상화되지 않습니다.

    SelectAll, SelectRange, 및 DeSelectRange 메서드를 사용하는 것이 SeletedItems 속성을 사용하는 것보다 선택 수정 시 훨씬 효율적입니다. 이러한 메서드는 항목 인덱스의 범위를 사용하여 항목을 선택(또는 선택 취소)합니다. 인덱스만 사용되므로 가상화된 항목이 가상화 상태를 유지합니다. 지정된 범위에 있는 모든 항목은 기존 선택 상태에 관계없이 선택되거나 선택 취소됩니다. SelectionChanged 이벤트는 이러한 메서드를 호출할 때마다 한 번만 발생합니다.

    Important

    SelectionMode 속성이 Multiple 또는 Extended로 설정된 경우에만 이러한 메서드를 호출해야 합니다. SelectionMode가 Single 또는 None일 때 SelectRange를 호출하면 예외가 throw됩니다.

    인덱스 범위를 사용하여 항목을 선택하는 경우 SelectedRanges 속성을 사용하여 list에서 선택한 모든 범위를 가져옵니다.

    ItemsSource 속성이 IItemsRangeInfo를 구현하고 이러한 메서드를 사용하여 선택 항목을 수정하는 경우, AddedItems과 RemovedItems 속성은 SelectionChangedEventArgs에서 설정되지 않습니다. 이러한 속성을 설정하려면 항목 객체의 가상화를 해제해야 합니다. 대신 SelectedRanges 속성을 사용하여 항목을 가져옵니다.

    SelectAll 메서드를 호출하여 컬렉션의 모든 항목을 선택할 수 있습니다. 그러나 모든 항목을 선택 취소하기 위한 메서드는 없습니다. DeselectRange를 호출하고 FirstIndex 값이 0이고 Length 값이 컬렉션의 항목 수와 같은 ItemIndexRange를 전달하여 모든 항목을 선택 취소할 수 있습니다. 이 내용은 모든 항목을 선택하는 옵션과 함께 다음 예제에서 나옵니다.

    <StackPanel Width="160">
        <Button Content="Select all" Click="SelectAllButton_Click"/>
        <Button Content="Deselect all" Click="DeselectAllButton_Click"/>
        <ListView x:Name="listView1" SelectionMode="Multiple">
            <x:String>Apricot</x:String>
            <x:String>Banana</x:String>
            <x:String>Cherry</x:String>
            <x:String>Orange</x:String>
            <x:String>Strawberry</x:String>
        </ListView>
    </StackPanel>
    
    private void SelectAllButton_Click(object sender, RoutedEventArgs e)
    {
        if (listView1.SelectionMode == ListViewSelectionMode.Multiple ||
            listView1.SelectionMode == ListViewSelectionMode.Extended)
        {
            listView1.SelectAll();
        }
    }
    
    private void DeselectAllButton_Click(object sender, RoutedEventArgs e)
    {
        if (listView1.SelectionMode == ListViewSelectionMode.Multiple ||
            listView1.SelectionMode == ListViewSelectionMode.Extended)
        {
            listView1.DeselectRange(new ItemIndexRange(0, (uint)listView1.Items.Count));
        }
    }
    

    선택한 항목의 모양을 변경하는 방법에 대한 자세한 내용은 항목 컨테이너 및 템플릿을 참조하세요.

    끌어서 놓기

    ListView 및 GridView 컨트롤은 자체 컨트롤 내에서, 그리고 자신과 다른 ListView 및 GridView 컨트롤 사이에서 항목을 끌어서 놓을 수 있도록 지원합니다. 드래그 앤 드롭 functionality 구현에 대한 자세한 내용은 드래그 앤 드롭을 참조하세요.

    샘플 코드 가져오기