본문 바로가기

C#, C++

WPF ItemsControl을 이용해서 UIelement를 반복해서 표현하는 방법(xaml에서 for문, foreach문을 대신해서 사용할 수 있는 방법)

WPF는 xaml, xaml.cs, viewmodel로 나누어서 프로그램을 만든다.

 

viewmodel이나 xaml.cs(비하인드 코드) 에서는 for문이나 while문, foreach문 같은 반복문을 손 쉽게 사용할 수 있다.

 

하지만, xaml에서 직접적으로 반복문을 사용하는 방법은 없는데 똑같은 이미지를 반복해서 넣는다거나

 

똑같은 버튼, 텍스트박스를 반복해서 넣는 경우, 또는 각 element마다 들어가는 Content가 조금씩 다르다거나

 

Grid.Row 나 width같은 속성들이 규칙적으로 바뀌어서 여러개가 들어가야 하는 경우, xaml에서 for문이나 while문 같은

 

것들이 사용되면 좋겠다고 생각하게 되는 경우가 많았다.

 

하지만 이는 현실적으로 불가능하고, 비하인드 코드에서 for문을 써서 넣으려고 하니 xaml.cs 코드가 지저분해 지는 것은

 

물론, 여러모로 어려운 점이 많았다.

 

그래서 인터넷 서핑으로 xaml코드 안에 반복문을 사용할 수 있는 방법이 없는지 알아보던 도중, ItemsControl을 사용하

 

면 비슷한 기능을 구현할 수 있다는 것을 알게되었다.

 

 

ItemsControl은 크게 3가지 부분으로 나누어진다.

 

        <ItemsControl ItemsSource="{Binding YourCollection}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <!--Grid, Stackpanel, Dockpanel 등 사용 할 panel의 종류를 정의하는 곳 -->
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <!-- panel에 들어갈 textbox, image, button 등의 element를 정의하는 곳-->
                </DataTemplate>
            </ItemsControl.ItemTemplate>
            <ItemsControl.ItemContainerStyle>
                <!-- element의 style을 정의하는 곳 (Grid.Row, width, event....)-->
            </ItemsControl.ItemContainerStyle>
        </ItemsControl>

이렇게 정의를 하면,

 

ViewModel에 정의해 놓은 콜렉션(또는 List)의 크기만큼 반복하면서 ItemTemplate안에 선언한 UIelement를 반복하면서 만들어준다. 아래는 내가 사용한 코드이다.

 

        <ItemsControl ItemsSource="{Binding Array100}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition/>
                            <RowDefinition/>
                            <RowDefinition/>
                            <RowDefinition/>
                            <RowDefinition/>
                            <RowDefinition/>
                            <RowDefinition/>
                            <RowDefinition/>
                            <RowDefinition/>
                            <RowDefinition/>
                        </Grid.RowDefinitions>
                    </Grid>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Content="{Binding num}">
                        <Button.InputBindings>
                            <MouseBinding Gesture="LeftClick" Command="{Binding RelativeSource={RelativeSource FindAncestor,
                                AncestorType={x:Type UserControl}}, Path=DataContext.LeftClick}" CommandParameter="{Binding num}"/>
                            <MouseBinding Gesture="RightClick" Command="{Binding RightClick}" CommandParameter="{Binding num}"/>
                        </Button.InputBindings>
                    </Button>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
            <ItemsControl.ItemContainerStyle>
                <Style TargetType="ContentPresenter">
                    <Setter Property="Grid.Row" Value="{Binding row}" />
                    <Setter Property="Grid.Column" Value="{Binding col}" />
                </Style>
            </ItemsControl.ItemContainerStyle>

        </ItemsControl>

 

사용한 panel은 10개의 row, 10개의 column을 가지는 Grid이고

 

들어가는 element는 버튼이다. 

 

ItemSource는 아래와 같은 Model을 사용하는 ObservableCollection이다.

 

모델
모델을 사용하는 콜렉션

 

생성자에서 이 Collection에 100개의 요소들을 넣는다. 따라서, 100개의 버튼이 생성 될 것이고

각 버튼의 Grid.Row나 Grid.Column은 row, col의 값을 따르고, 표시되는 Content는 num을 바인딩 할 것이다.

 

----------------------------------결과물-------------------------------------