티스토리 뷰

반응형

2022.09.06 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내v1.0 part9-2 StyleSelector

2022.08.31 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part9-1 DataTemplateSelector

2022.08.08 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part8-3 Template

2022.08.02 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part8-2 Template

2022.07.21 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part8-1 Template

2022.07.13 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part7 Behavior

2022.07.05 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part6 Command

2022.06.27 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part5 Converter

2022.06.15 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part4-2 Data Binding

2022.06.13 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part4-1 Data Binding

2022.06.07 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part3-3

2022.06.02 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part3-2

2022.05.30 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part3-1

2022.05.11 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part2

2022.05.09 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 v1.0 part1

1. ItemsControl

셈플 코드

<ItemsControl
    x:Name="ItemsControl"
    BorderBrush="Red"
    BorderThickness="1"
    DisplayMemberPath="Name" />

실행 결과 - 빨간색 테두리로 표시되는 부분이 ItemsControl 영역 입니다.

데이터는 코드 비하인드에서 ItemsSource에 List<Person>()을 입력했습니다.

위의 이미를 참고하여, ItemsControl의 일반적인 내용과 내부 구조를 알아보도록 하겠습니다.

  • 목록 데이터를 표시하기위한 기본 컨트롤 입니다.
  • 내부 구조가 간단하고 가볍기 때문에 여러가지 용도로 활용합니다. 저는 RadioButton을 여러개 배치해서 사용할 때 주로 사용합니다.
  • ListBox, ComboBox 등의 컨트롤은 ItemsControl을 상속 받은 컨트롤 입니다.
  • ItemsSource, DisplayMemberPath, ItemTemplate, ItemsPanel, ItemContainerStyle 프로퍼티 등을 가지고 있습니다.
  • Selector가 아니기 때문에 Selected...로 시작하는 프로퍼티는 가지고 있지 않습니다. 그래서 선택 기능이 없습니다.
  • 1개의 ItemsPresenter, 각 Item은 1개의 ContentPresenter를 가지고 있습니다. ContentPresenter 내부에 DataTemplate가 없는 경우 TextBlock가 기본적으로 사용됩니다.
  • ItemTemplate는 ContentPresenter 내부에 Data를 효과적으로 표시하기 위한 용도로 사용됩니다.
  • ItemsPanel에 입력되는 ItemsPanelTemplate는 ContentPresenter를 어떤 방식으로 배치할지를 지정하는 역할을 합니다. 기본적으로는 StackPanel이 사용되며, 각 Item들은 세로 방향으로 표시됩니다.
.NET 6로 만들어진 WPF 프로젝트에서 구조를 확인했습니다. .Net Framework WPF와는 다를 수 있습니다.

2. ItemTemplate 작성하기

  • DisplayMemberPath와는 함께 사용할 수 없습니다.
  • 반드시 DataTemplate, HierarchicalDataTemplate  둘 중 1가지만 사용할 수 있습니다.
  • 일반적으로 Template 내부에는 <Border/> 혹은 <Grid/> 1개를 추가하고, 자유롭게 디자인 합니다.
<ItemsControl
    x:Name="ItemsControl"
    BorderBrush="Red"
    BorderThickness="1">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="20" />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <TextBlock Text="{Binding Id}" />
                <TextBlock Grid.Column="1" Text="{Binding Name}" />
                <TextBlock Grid.Column="2" Text="{Binding Sex}" />
                <TextBlock Grid.Column="3" Text="{Binding Description}" />
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

DataTemplate 내부는 최대한 이쁘게 만드는 것이 최고입니당~

3. ItemsPanelTemplate 작성하기

ItemsPanelTemplate 생성하기

Document Outline -> ItemsControl 마우스 오른쪽 -> Edit Additional Templates -> Edit Layout of Items (ItemsPanel) -> Create Empty 선택

기본 아이템 레이아웃 컨트롤을 볼 수 있습니다.

<ItemsPanelTemplate x:Key="ItemsControlItemsPanel0">
    <StackPanel />
</ItemsPanelTemplate>

ItemsControl의 아이템 출력 방향을 세로가 아닌 가로 방향으로 변경

위에서 작성한 ItemTemplate는 ItemTemplate1이라는 StaticResource로 위치를 이동해서 재사용하고 있습니다.
<ItemsPanelTemplate x:Key="ItemsControlItemsPanel1">
    <StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>

<ItemsControl
    x:Name="ItemsControl1"
    BorderBrush="Red"
    BorderThickness="1"
    ItemTemplate="{StaticResource ItemTemplate1}"
    ItemsPanel="{StaticResource ItemsControlItemsPanel1}" />

가로 방향으로 추가되다가 화면 끝에 도달하면, 자동 줄 변경

<ItemsPanelTemplate x:Key="ItemsControlItemsPanel2">
    <WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>

<ItemsControl
    x:Name="ItemsControl2"
    BorderBrush="Blue"
    BorderThickness="1"
    ItemTemplate="{StaticResource ItemTemplate1}"
    ItemsPanel="{StaticResource ItemsControlItemsPanel2}" />

Canvas를 이용해서 아이템을 원하는 위치에 출력

Person 모델에 X, Y 프로퍼티를 추가해서 위치 정보를 입력했습니다.
var list = new List<Person>
{
    new Person { Id = 1, Name = "kaki104", Sex = true, Description = "Item1" , X = 0, Y = 210},
    new Person { Id = 2, Name = "kaki105", Sex = false, Description = "Item2", X = 50, Y = 160},
    new Person { Id = 3, Name = "kaki106", Sex = true, Description = "Item3", X = 100, Y = 110},
    new Person { Id = 4, Name = "kaki107", Sex = false, Description = "Item4", X = 150, Y = 60},
    new Person { Id = 5, Name = "kaki108", Sex = true, Description = "Item5", X = 200, Y = 10},
};
<ItemsPanelTemplate x:Key="ItemsControlItemsPanel3">
    <Canvas IsItemsHost="True" />
</ItemsPanelTemplate>

<ItemsControl
    x:Name="ItemsControl3"
    Grid.Column="1"
    BorderThickness="1"
    ItemTemplate="{StaticResource ItemTemplate1}"
    ItemsPanel="{StaticResource ItemsControlItemsPanel3}">
    <ItemsControl.Resources>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding X}" />
            <Setter Property="Canvas.Top" Value="{Binding Y}" />
        </Style>
    </ItemsControl.Resources>
</ItemsControl>

실행 결과

3. 마무리

하나의 데이터를 어떻게 이쁘게 보이게 꾸밀 것인지는 ItemTemplate가 담당하고, 데이터들을 어떻게 배치할지를 정하는 것은 ItemsPanel이 담당하고 있다는 것을 설명 드렸습니다. 추가로 궁금하신 사항은 리플 남겨주시면 답변드리겠습니다.

4. 소스는 part8-3에서 링크를 추가하도록 하겠습니다.

 

반응형
댓글