728x90
반응형
728x170
■ DataGrid 클래스를 사용해 그룹핑, 정렬 및 필터링을 사용하는 방법을 보여준다.
▶ 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
반응형
그리드형(광고전용)
'C# > WPF' 카테고리의 다른 글
[C#/WPF] 글자 애니메이션 사용하기 (0) | 2018.02.18 |
---|---|
[C#/WPF] MarkupExtension 클래스 : 마크업 확장 사용하기 (0) | 2018.02.18 |
[C#/WPF] MediaElement 클래스 : 동영상 재생하기 (0) | 2017.06.14 |
[C#/WPF] ListView 클래스 : 그리드 뷰 컬럼 헤더 클릭시 정렬하기 (0) | 2017.06.11 |
[C#/WPF] DataGrid 클래스 : RowValidationRules 속성을 사용해 검증하기 (0) | 2017.06.11 |
[C#/WPF] 방사형 패널 사용하기 (0) | 2017.06.11 |
[C#/WPF] MessageBox 클래스 : 메시지 박스 사용하기 (0) | 2017.06.11 |
[C#/WPF] DataGrid 클래스 : ADO.NET 엔터티 데이터 모델 바인딩 하기 (0) | 2017.06.11 |
[C#/WPF] 애니메이션 버튼 사용하기 (0) | 2017.06.11 |
[C#/WPF] DesignInstance 확장 태그 사용하기 (0) | 2017.06.11 |
댓글을 달아 주세요