티스토리 뷰

반응형

Group을 추가하는 방법에 대해서 검색해보면 대부분 Code를 이용해서 CollectionViewSource를 생성해서 사용하는 방법이 나오고, MVVM Pattern에서는 어떻게하는지 잘 나오지 않습니다. 그래서, CollectionViewSource에 대해서 간단히 알아보고, MVVM Pattern에서는 어떻게 사용하는지 알아보도록 하겠습니다.

 

1. CollectionViewSource

CollectionView클래스의 파생된 클래스로, CollectionView 속성을 설정하고, 설정된 기본 보기를 다른 컨트롤에 전달할 수 있는 기능이 있습니다.

 

정리를 하자면, 컨틀로과 뷰모델 사이에 CollectionViewSource 인스턴스가 하나더 있으면서, Sort, Filter, Group을 원본 데이터의 변경없이 처리할 수 있는 녀석입니다.

CollectionViewSource에 대한 더 자세한 사항은 여기를 참고하시기바랍니다.

 

2. CollectionViewSource를 xaml에서 사용하기

코드로 인스턴스를 만들어서 사용하수도 있지만, 이 녀석은 아무래도 resource로 만들어서 사용하는 것이 더 편하게 사용할 수 있습니다.

 

예제에서는 Window.Resources에 CVS라는 이름으로 추가를 했습니다. Source는 ViewModel에 있는 Animals를 입력해줍니다. Animal type에는 Type이라는 속성이 있는데, 동물,식물,새 등의 구분을 가지고 있으며, 그 속성을 그룹핑 할 때 사용한다는 것입니다. PropertyName은 일반 프로퍼티이기 때문에 바인딩은 않됩니다.

    <Window.Resources>
        <CollectionViewSource x:Key="CVS" Source="{Binding Animals}">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="Type" />
            </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </Window.Resources>

2. 컨트롤에 사용

ListView나 DataGrid 컨트롤의 ItemsSource 프로퍼티에 CVS를 입력합니다.

<ListView ItemsSource="{Binding Source={StaticResource CVS}}"...>

<DataGrid ItemsSource="{Binding Source={StaticResource CVS}}"...>

3. 중간결과

Group이 된 모습을 확인할 수 있습니다. 그렇지만, UI에도 그룹이 되었다는 것을 쉽게 표현을 해주어야 하기 때문에 Group 속성을 추가로 입력합니다.

4. GroupStyle 추가

ListView와 DataGrid 두곳에 스타일을 적용해야하기 때문에 Resource에 GroupStyle이라는 스타일을 생성합니다.

여기서 사용한 스타일에 대해 더 자세한 사항은 여기를 참고하시면 될 것 같습니다.

DataGrid에서 사용할 수 있는 추가 스타일은 여기를 참고하시면 됩니다.

        <Style x:Key="GroupStyle" TargetType="{x:Type GroupItem}">
            <Setter Property="Margin" Value="0,0,0,5" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type GroupItem}">
                        <Expander
                            BorderBrush="#FFA4B97F"
                            BorderThickness="0,0,0,1"
                            IsExpanded="True">
                            <Expander.Header>
                                <DockPanel>
                                    <TextBlock
                                        Width="100"
                                        Margin="5,0,0,0"
                                        FontWeight="Bold"
                                        Text="{Binding Path=Name}" />
                                    <TextBlock FontWeight="Bold" Text="{Binding Path=ItemCount}" />
                                </DockPanel>
                            </Expander.Header>
                            <Expander.Content>
                                <ItemsPresenter />
                            </Expander.Content>
                        </Expander>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

5. ListView와 DataGrid에 GroupStyle적용

BaseOn을 이용해서 GroupStyle을 기본으로 가져오도록 만들어서 두개의 컨트롤에 모두 스타일을 적용하도록 하였습니다.

        <ListView ItemsSource="{Binding Source={StaticResource CVS}}">
            <ListView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.ContainerStyle>
                        <Style BasedOn="{StaticResource GroupStyle}" TargetType="{x:Type GroupItem}" />
                    </GroupStyle.ContainerStyle>
                </GroupStyle>
            </ListView.GroupStyle>
            ...
        </ListView>
        
        <DataGrid
            x:Name="DataGrid"
            Grid.Column="1"
            AutoGenerateColumns="False"
            CanUserAddRows="False"
            ItemsSource="{Binding Source={StaticResource CVS}}">
            <DataGrid.GroupStyle>
                <GroupStyle>
                    <GroupStyle.ContainerStyle>
                        <Style BasedOn="{StaticResource GroupStyle}" TargetType="{x:Type GroupItem}" />
                    </GroupStyle.ContainerStyle>
                </GroupStyle>
            </DataGrid.GroupStyle>
            ...
        </DataGrid>

6. 실행화면

GroupItem에 Expender를 추가해서 접었다/폈다 할 수 있게 만들었습니다. 소스를 이용해서 여러분만의 스타일을 적용할 수도 있으니 마음대로 수정해서 사용하시면 됩니다.

7. 코드

ListViewSample에 ListViewGroup.xaml, ListViewGroupViewModel.cs를 참고하시면 됩니다.

WpfTest/ListViewSample at master · kaki104/WpfTest (github.com)

 

GitHub - kaki104/WpfTest

Contribute to kaki104/WpfTest development by creating an account on GitHub.

github.com

 

반응형
댓글