첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

■ DataGrid 클래스를 사용해 그룹핑, 정렬 및 필터링을 사용하는 방법을 보여준다.

TestProject.zip
다운로드

▶ Task.cs

using System;
using System.ComponentModel;

namespace TestProject
{
    /// <summary>
    /// 작업
    /// </summary>
    public class Task : INotifyPropertyChanged, IEditableObject
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Event
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 속성 변경시 - PropertyChanged

        /// <summary>
        /// 속성 변경시
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 프로젝트명
        /// </summary>
        private string projectName = string.Empty;

        /// <summary>
        /// 작업명
        /// </summary>
        private string taskName = string.Empty;

        /// <summary>
        /// 기한
        /// </summary>
        private DateTime dueDate = DateTime.Now;

        /// <summary>
        /// 완료 여부
        /// </summary>
        private bool completed = false;

        /// <summary>
        /// 임시 작업
        /// </summary>
        private Task temporaryTask = null;

        /// <summary>
        /// 편집 여부
        /// </summary>
        private bool editing = false;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 프로젝트명 - ProjectName

        /// <summary>
        /// 프로젝트명
        /// </summary>
        public string ProjectName
        {
            get
            {
                return this.projectName;
            }
            set
            {
                if(value != this.projectName)
                {
                    this.projectName = value;

                    NotifyPropertyChanged("ProjectName");
                }
            }
        }

        #endregion
        #region 작업명 - TaskName

        /// <summary>
        /// 작업명
        /// </summary>
        public string TaskName
        {
            get
            {
                return this.taskName;
            }
            set
            {
                if(value != this.taskName)
                {
                    this.taskName = value;

                    NotifyPropertyChanged("TaskName");
                }
            }
        }

        #endregion
        #region 기한 - DueDate

        /// <summary>
        /// 기한
        /// </summary>
        public DateTime DueDate
        {
            get
            {
                return this.dueDate;
            }
            set
            {
                if(value != this.dueDate)
                {
                    this.dueDate = value;

                    NotifyPropertyChanged("DueDate");
                }
            }
        }

        #endregion
        #region 완료 여부 - Completed

        /// <summary>
        /// 완료 여부
        /// </summary>
        public bool Completed
        {
            get
            {
                return this.completed;
            }
            set
            {
                if(value != this.completed)
                {
                    this.completed = value;

                    NotifyPropertyChanged("Completed");
                }
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 편집 시작하기 - BeginEdit() (IEditableObject)

        /// <summary>
        /// 편집 시작하기
        /// </summary>
        public void BeginEdit()
        {
            if(this.editing == false)
            {
                this.temporaryTask = MemberwiseClone() as Task;

                this.editing = true;
            }
        }

        #endregion
        #region 편집 취소하기 - CancelEdit() (IEditableObject)

        /// <summary>
        /// 편집 취소하기
        /// </summary>
        public void CancelEdit()
        {
            if(this.editing == true)
            {
                ProjectName = this.temporaryTask.ProjectName;
                TaskName    = this.temporaryTask.TaskName;
                DueDate     = this.temporaryTask.DueDate;
                Completed   = this.temporaryTask.Completed;

                this.editing = false;
            }
        }

        #endregion
        #region 편집 완료하기 - EndEdit() (IEditableObject)

        /// <summary>
        /// 편집 완료하기
        /// </summary>
        public void EndEdit()
        {
            if(this.editing == true)
            {
                this.temporaryTask = null;

                this.editing = false;
            }
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 속성 변경시 통지하기 - NotifyPropertyChanged(propertyName)

        /// <summary>
        /// 속성 변경시 통지하기
        /// </summary>
        /// <param name="propertyName">속성명</param>
        private void NotifyPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }
}

 

▶ MainWindow.xaml

<Window
    x:Class="TestProject.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
    xmlns:local="clr-namespace:TestProject"
    Width="800"
    Height="600"
    Title="DataGrid 클래스 : 그룹핑, 정렬 및 필터링 사용하기"
    FontFamily="나눔고딕코딩"
    FontSize="16">
    <Window.Resources>
        <local:CompletedValueConverter x:Key="CompletedValueConverterKey" />
        <local:TaskCollection x:Key="TaskCollectionKey" />
        <CollectionViewSource
            x:Key="CollectionViewSourceKey"
            Source="{StaticResource TaskCollectionKey}"
            Filter="taskCollectionViewSource_Filter">
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="ProjectName" />
                <scm:SortDescription PropertyName="Completed"   />
                <scm:SortDescription PropertyName="DueDate"     />
            </CollectionViewSource.SortDescriptions>
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="ProjectName" />
                <PropertyGroupDescription PropertyName="Completed"   />
            </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition             />
            <RowDefinition Height="30" />
        </Grid.RowDefinitions>
        <DataGrid x:Name="dataGrid"
            CanUserAddRows="False"
            ItemsSource="{Binding Source={StaticResource CollectionViewSourceKey}}">
            <DataGrid.GroupStyle>
                <GroupStyle>
                    <GroupStyle.ContainerStyle>
                        <Style TargetType="{x:Type GroupItem}">
                            <Setter Property="Margin" Value="0 0 0 5"/>
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="{x:Type GroupItem}">
                                        <Expander
                                            BorderBrush="#ff002255"
                                            BorderThickness="1 1 1 5"
                                            Foreground="#ffeeeeee"
                                            Background="#ff112255"
                                            IsExpanded="True">
                                            <Expander.Header>
                                                <DockPanel>
                                                    <TextBlock
                                                        Margin="5 0 0 0"
                                                        Width="100"
                                                        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>
                    </GroupStyle.ContainerStyle>
                </GroupStyle>
                <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <DockPanel Background="LightBlue">
                                <TextBlock
                                    Margin="30 0 0 0"
                                    Width="100"
                                    Foreground="Blue"
                                    Text="{Binding Path=Name, Converter={StaticResource CompletedValueConverterKey}}" />
                                <TextBlock
                                    Foreground="Blue"
                                    Text="{Binding Path=ItemCount}" />
                            </DockPanel>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                </GroupStyle>
            </DataGrid.GroupStyle>
            <DataGrid.RowStyle>
                <Style TargetType="{x:Type DataGridRow}">
                    <Setter Property="Foreground" Value="Black" />
                    <Setter Property="Background" Value="White" />
                </Style>
            </DataGrid.RowStyle>
        </DataGrid>
        <StackPanel Grid.Row="1"
            Orientation="Horizontal">
            <TextBlock
                VerticalAlignment="Center"
                Text=" 완료 항목 필터링 하기 " />
            <CheckBox x:Name="filterCheckBox"
                VerticalAlignment="Center"
                Checked="filterCheckBox_Checked"
                Unchecked="filterCheckBox_Checked" />
            <Button
                Margin="10 2 2 2"
                Content="그룹 제거하기"
                Click="ungroupButton_Click" />
            <Button
                Margin="2"
                Content="Project/Status 그룹 설정하기"
                Click="groupButton_Click" />
        </StackPanel>
    </Grid>
</Window>

 

▶ MainWindow.xaml.cs

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;

namespace TestProject
{
    /// <summary>
    /// 메인 윈도우
    /// </summary>
    public partial class MainWindow : Window
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainWindow()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();

            TaskCollection collection = Resources["TaskCollectionKey"] as TaskCollection;

            for(int i = 1; i <= 14; i++)
            {
                collection.Add
                (
                    new Task()
                    {
                        ProjectName = "Project " + ((i % 3) + 1).ToString(),
                        TaskName    = "Task " + i.ToString(),
                        DueDate     = DateTime.Now.AddDays(i),
                        Completed   = (i % 2 == 0)
                    }
                );
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 작업 컬렉션 뷰 소스 필터시 처리하기 - taskCollectionViewSource_Filter(sender, e)

        /// <summary>
        /// 작업 컬렉션 뷰 소스 필터시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void taskCollectionViewSource_Filter(object sender, FilterEventArgs e)
        {
            Task task = e.Item as Task;

            if(task != null)
            {
                if(this.filterCheckBox.IsChecked == true && task.Completed == true)
                {
                    e.Accepted = false;
                }
                else
                {
                    e.Accepted = true;
                }
            }
        }

        #endregion
        #region 필터 체크 박스 체크시 처리하기 - filterCheckBox_Checked(sender, e)

        /// <summary>
        /// 필터 체크 박스 체크시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void filterCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            CollectionViewSource.GetDefaultView(this.dataGrid.ItemsSource).Refresh();
        }

        #endregion
        #region 그룹 해제 버튼 클릭시 처리하기 - ungroupButton_Click(sender, e)

        /// <summary>
        /// 그룹 해제 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void ungroupButton_Click(object sender, RoutedEventArgs e)
        {
            ICollectionView collectionView = CollectionViewSource.GetDefaultView(this.dataGrid.ItemsSource);

            if(collectionView != null)
            {
                collectionView.GroupDescriptions.Clear();
            }
        }

        #endregion
        #region 그룹 버튼 클릭시 처리하기 - groupButton_Click(sender, e)

        /// <summary>
        /// 그룹 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void groupButton_Click(object sender, RoutedEventArgs e)
        {
            ICollectionView collectionView = CollectionViewSource.GetDefaultView(this.dataGrid.ItemsSource);

            if(collectionView != null && collectionView.CanGroup == true)
            {
                collectionView.GroupDescriptions.Clear();

                collectionView.GroupDescriptions.Add(new PropertyGroupDescription("ProjectName"));
                collectionView.GroupDescriptions.Add(new PropertyGroupDescription("Completed"  ));
            }
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요