728x90
728x170
■ DataTemplateSelector 엘리먼트를 사용해 데이터 객체 속성에 따라 DataTemplate 객체를 선택하는 방법을 보여준다.
▶ TaskType.cs
namespace TestProject
{
/// <summary>
/// 작업 타입
/// </summary>
public enum TaskType
{
/// <summary>
/// 홈
/// </summary>
Home,
/// <summary>
/// 작업
/// </summary>
Work
}
}
▶ Task.cs
using System.ComponentModel;
namespace TestProject
{
/// <summary>
/// 작업
/// </summary>
public class Task : INotifyPropertyChanged
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Event
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 속성 변경시 - PropertyChanged
/// <summary>
/// 속성 변경시
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 명칭
/// </summary>
private string name;
/// <summary>
/// 설명
/// </summary>
private string description;
/// <summary>
/// 우선 순위
/// </summary>
private int priority;
/// <summary>
/// 작업 타입
/// </summary>
private TaskType type;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 명칭 - Name
/// <summary>
/// 명칭
/// </summary>
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
FirePropertyChangedEvent("Name");
}
}
#endregion
#region 설명 - Description
/// <summary>
/// 설명
/// </summary>
public string Description
{
get
{
return this.description;
}
set
{
this.description = value;
FirePropertyChangedEvent("Description");
}
}
#endregion
#region 우선 순위 - Priority
/// <summary>
/// 우선 순위
/// </summary>
public int Priority
{
get
{
return this.priority;
}
set
{
this.priority = value;
FirePropertyChangedEvent("Priority");
}
}
#endregion
#region 작업 타입 - Type
/// <summary>
/// 작업 타입
/// </summary>
public TaskType Type
{
get
{
return this.type;
}
set
{
this.type = value;
FirePropertyChangedEvent("Type");
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - Task()
/// <summary>
/// 생성자
/// </summary>
public Task()
{
}
#endregion
#region 생성자 - Task(name, description, priority, type)
/// <summary>
/// 생성자
/// </summary>
/// <param name="name">명칭</param>
/// <param name="description">설명</param>
/// <param name="priority">우선 순위</param>
/// <param name="type">작업 타입</param>
public Task(string name, string description, int priority, TaskType type)
{
this.name = name;
this.description = description;
this.priority = priority;
this.type = type;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 문자열 구하기 - ToString()
/// <summary>
/// 문자열 구하기
/// </summary>
/// <returns>문자열</returns>
public override string ToString() => this.name;
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Protected
#region 속성 변경시 이벤트 발생시키기 - FirePropertyChangedEvent(propertyName)
/// <summary>
/// 속성 변경시 이벤트 발생시키기
/// </summary>
/// <param name="propertyName">속성명</param>
protected void FirePropertyChangedEvent(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}
▶ TaskCollection.cs
using System.Collections.ObjectModel;
namespace TestProject
{
/// <summary>
/// 작업 컬렉션
/// </summary>
public class TaskCollection : ObservableCollection<Task>
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - TaskCollection()
/// <summary>
/// 생성자
/// </summary>
public TaskCollection()
{
Add(new Task("Groceries", "Pick up Groceries and Detergent", 2, TaskType.Home));
Add(new Task("Laundry" , "Do my Laundry" , 2, TaskType.Home));
Add(new Task("Email" , "Email clients" , 1, TaskType.Work));
Add(new Task("Clean" , "Clean my office" , 3, TaskType.Work));
Add(new Task("Dinner" , "Get ready for family reunion" , 1, TaskType.Home));
Add(new Task("Proposals", "Review new budget proposals" , 2, TaskType.Work));
}
#endregion
}
}
▶ TaskListDataTemplateSelector.cs
using System.Windows;
using System.Windows.Controls;
namespace TestProject
{
/// <summary>
/// 작업 목록 데이터 템플리트 선택자
/// </summary>
public class TaskListDataTemplateSelector : DataTemplateSelector
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 템플리트 선택하기 - SelectTemplate(item, container)
/// <summary>
/// 템플리트 선택하기
/// </summary>
/// <param name="item">항목</param>
/// <param name="container">컨테이너</param>
/// <returns>데이터 템플리트</returns>
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if(item != null && item is Task)
{
Task task = item as Task;
Window window = Application.Current.MainWindow;
if(task.Priority == 1)
{
return window.FindResource("ImportantTaskTemplateKey") as DataTemplate;
}
return window.FindResource("MyTaskTemplateKey") as DataTemplate;
}
return null;
}
#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:local="clr-namespace:TestProject"
Width="800"
Height="600"
Title="TestProject"
FontFamily="나눔고딕코딩"
FontSize="16">
<Window.Resources>
<local:TaskCollection x:Key="TaskCollectionKey" />
<local:TaskListDataTemplateSelector x:Key="TaskListDataTemplateSelectorKey"/>
<DataTemplate x:Key="ImportantTaskTemplateKey">
<DataTemplate.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="20" />
</Style>
</DataTemplate.Resources>
<Border Name="border"
Margin="5"
BorderThickness="1"
BorderBrush="Red"
Padding="5">
<DockPanel HorizontalAlignment="Center">
<TextBlock Text="{Binding Path=Description}" />
<TextBlock>!</TextBlock>
</DockPanel>
</Border>
</DataTemplate>
<DataTemplate x:Key="MyTaskTemplateKey">
<Border Name="border"
Margin="5"
BorderThickness="1"
BorderBrush="Aqua"
Padding="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="작업명 :" />
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=Name}" />
<TextBlock Grid.Row="1" Grid.Column="0" Text="설명 :" />
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=Description}" />
<TextBlock Grid.Row="2" Grid.Column="0" Text="우선 순위 :" />
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=Priority}" />
</Grid>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=Type}">
<DataTrigger.Value>
<local:TaskType>Home</local:TaskType>
</DataTrigger.Value>
<Setter
TargetName="border"
Property="BorderBrush"
Value="Yellow" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>
<StackPanel Margin="10">
<TextBlock
FontSize="18"
Text="나의 작업 목록 :" />
<ListBox
ItemTemplateSelector="{StaticResource TaskListDataTemplateSelectorKey}"
HorizontalContentAlignment="Stretch"
Margin="10"
Width="400"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Source={StaticResource TaskCollectionKey}}" />
<TextBlock
FontSize="18"
Text="설명 :" />
<ContentControl
ContentTemplate="{StaticResource MyTaskTemplateKey}"
Margin="10"
Content="{Binding Source={StaticResource TaskCollectionKey}}" />
</StackPanel>
</Window>
728x90
그리드형(광고전용)
'C# > WPF' 카테고리의 다른 글
[C#/WPF] IValueConverter 인터페이스 사용하기 (0) | 2023.02.23 |
---|---|
[C#/WPF] Binding 태그 확장 : Source 속성을 사용해 열거형 바인딩하기 (0) | 2023.02.22 |
[C#/WPF] Binding 태그 확장 : Source 속성을 사용해 컬렉션 바인딩 및 선택 정보 표시하기 (0) | 2023.02.22 |
[C#/WPF] Binding 엘리먼트 : Source/Path/UpdateSourceTrigger 속성을 사용해 단순 바인딩 설정하기 (0) | 2023.02.18 |
[C#/WPF] ItemsControl 엘리먼트 : ItemsPanel/ItemTemplate/ItemContainerStyle/Template 속성을 사용해 스타일 및 템플리트 설정하기 (0) | 2023.02.17 |
[C#/WPF] 데이터 바인딩 사용하기 (0) | 2023.02.16 |
[C#/WPF] IValueConverter 인터페이스 : 날짜/시간↔문자열 변환자 사용하기 (0) | 2023.02.12 |
[C#/WPF] ValidationRule 클래스 : 현재 날짜보다 미래 날짜 여부 검증하기 (0) | 2023.02.12 |
[C#/WPF] IMultiValueConverter 인터페이스 사용하기 (0) | 2023.02.12 |
[C#/WPF] ControlTemplate 엘리먼트 : Window 엘리먼트 정의하기 (0) | 2023.02.11 |