이전 포스트에서는 데이타템플릿(DataTemplate)이 하는 기능을 알아보았고 컨버터(Converter)를 이용해 내가 보낸 메시지와 다른 사람이 보낸 메시지를 다르게 보이게 하는 방법을 살펴봤습니다. 이번 포스트에서는 셀렉터(Selector)가 어떤 기능을 하는지 어떻게 사용하는지 살펴봅니다.
1 2 3 4 5 6 7 8 9 10 11 12 | <!-- Template Selector --> <DataTemplate x:Key="DataTemplate_Message_Left" DataType="{x:Type local:ExchangeMessage}"> <StackPanel> <TextBlock Text="{Binding Name}" Visibility="{Binding IsMine, Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter=inverted}"/> <Border Background="{Binding IsMine, Converter={StaticResource BooleanToBrushConverter}}" CornerRadius="5" Margin="0,3"> <TextBlock Text="{Binding Message}" TextWrapping="Wrap" Grid.Column="1" FontSize="11" Margin="5,3,5,7"/> </Border> <TextBlock x:Name="PART_Time" Text="{Binding ConfirmedTime, StringFormat=hh:mm:ss}" FontSize="8"/> </DataTemplate> | cs |
기존의 데이타템플릿의 키값을 DataTemplate_Message_Left로 변경하고 전체 XAML 코드를 [복사 > 붙여넣기]합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | <DataTemplate x:Key="DataTemplate_Message_Right" DataType="{x:Type local:ExchangeMessage}"> <StackPanel> <TextBlock Text="{Binding Name}" Visibility="{Binding IsMine, Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter=inverted}"/> <Border Background="{Binding IsMine, Converter={StaticResource BooleanToBrushConverter}}" CornerRadius="5" Margin="0,3"> <TextBlock Text="{Binding Message}" TextWrapping="Wrap" Grid.Column="1" FontSize="11" Margin="5,3,5,7"/> </Border> <TextBlock x:Name="PART_Time" Text="{Binding ConfirmedTime, StringFormat=hh:mm:ss}" FontSize="8" HorizontalAlignment="Right"/> </StackPanel> </DataTemplate> | cs |
복사+붙여넣기한 데이타템플릿의 키값은 DataTemplate_Message_Right으로 변경합니다. 데이타템플릿이 2개 준비되었습니다. 확인 시간을 오른쪽으로 정렬하기 위해 PART_Time의 HorizontalAlignment 속성을 Right로 선언했습니다.
MessageStyleTemplateSelector.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class MessageTemplateSelector : DataTemplateSelector { public DataTemplate LeftTemplate { get; set; } public DataTemplate RightTemplate { get; set; } public string PropertyToCheck { get; set; } public string PropertyValue { get; set; } public override DataTemplate SelectTemplate(object item, DependencyObject container) { var exchangeMessage = (ExchangeMessage)item; var type = exchangeMessage.GetType(); var property = type.GetProperty(PropertyToCheck); if (property.GetValue(exchangeMessage, null).ToString() == PropertyValue) { return RightTemplate; } else { return LeftTemplate; } } } | cs |
DataTemplateSelector를 상속 받은 MessageTemplateSelector를 추가합니다. SelectTemplate 메소드를 재정의합니다. Selector를 작성할 때 이 메소드를 재정의하는 일은 필수입니다. 사용자가 지정한 프로퍼티(PropertyToCheck)에 지정한 값(PropertyValue)이 일치하면 지정한 데이터템플릿을 리턴하도록 코드를 작성했습니다.
1 | xmlns:slt="clr-namespace:Sample.Selector" | cs |
셀렉터를 XAML 코드에서 사용하려면 네임스페이스를 선언해야 합니다.
1 2 3 4 | <slt:MessageTemplateSelector x:Key="MessageTemplateSelector" PropertyToCheck="IsMine" PropertyValue="True" LeftTemplate="{StaticResource DataTemplate_Message_Left}" RightTemplate="{StaticResource DataTemplate_Message_Right}"/> | cs |
MessageTemplateSelector를 리소스에 선언합니다. 이전 포스트에서는 IsMine 프로퍼티에 True 값이 될때 컨버터가 동작하도록 했었습니다. 이번에도 마찬가지 방식으로 지정한 데이타템플릿이 리턴되도록 했습니다.
1 2 3 4 5 6 7 8 9 10 11 | <!-- Style & Template Selector --> <ListBox ItemTemplateSelector="{StaticResource MessageTemplateSelector}" Grid.Column="1"> <ListBox.ItemsSource> <x:Array Type="{x:Type local:ExchangeMessage}"> <local:ExchangeMessage Name="X Friend" Message="Charles~ R u there?" ConfirmedTime="2018-03-01 12:24:33" IsMine="False"/> <local:ExchangeMessage Name="Me" Message="Yeah~ i'm here. What's up?" ConfirmedTime="2018-03-01 12:25:44" IsMine="True"/> <local:ExchangeMessage Name="X Friend" Message="Do u have time tonight? Let's get it!" ConfirmedTime="2018-03-01 12:26:55" IsMine="False"/> </x:Array> </ListBox.ItemsSource> </ListBox> | cs |
ItemTemplateSelector 속성에 셀렉터를 선언합니다.
확인 시간이 오른쪽으로 정렬되었습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <!-- Style Selector --> <Style x:Key="Style_Message_Left" TargetType="{x:Type ListBoxItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBoxItem}"> <ContentPresenter x:Name="PART_ListBoxItem" HorizontalAlignment="Left" Margin="5,0,20,5"/> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="Style_Message_Right" TargetType="{x:Type ListBoxItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBoxItem}"> <ContentPresenter x:Name="PART_ListBoxItem" HorizontalAlignment="Right" Margin="20,0,5,5"/> </ControlTemplate> </Setter.Value> </Setter> </Style> | cs |
추가로 스타일셀렉터를 살펴봅니다. 아이템 전체를 오른쪽으로 정렬하려고 합니다. 데이타템플릿과 마찬가지로 Style_Message_Left, Style_Message_Right 2개의 스타일을 정의합니다. PART_ListBoxItem의 HorizontalAlignment, Margin 속성을 서로 반대로 정의합니다.
1 2 3 4 | <slt:MessageStyleSelector x:Key="MessageStyleSelector" PropertyToCheck="IsMine" PropertyValue="True" LeftStyle="{StaticResource Style_Message_Left}" RightStyle="{StaticResource Style_Message_Right}"/> | cs |
MessageTemplateSelector와 마찬가지로 MessageStyleSelector를 리소스에 선언합니다.
1 2 3 4 5 6 7 8 9 10 11 12 | <!-- Style & Template Selector --> <ListBox ItemTemplateSelector="{StaticResource MessageTemplateSelector}" ItemContainerStyleSelector="{StaticResource MessageStyleSelector}" Grid.Column="1"> <ListBox.ItemsSource> <x:Array Type="{x:Type local:ExchangeMessage}"> <local:ExchangeMessage Name="X Friend" Message="Charles~ R u there?" ConfirmedTime="2018-03-01 12:24:33" IsMine="False"/> <local:ExchangeMessage Name="Me" Message="Yeah~ i'm here. What's up?" ConfirmedTime="2018-03-01 12:25:44" IsMine="True"/> <local:ExchangeMessage Name="X Friend" Message="Do u have time tonight? Let's get it!" ConfirmedTime="2018-03-01 12:26:55" IsMine="False"/> </x:Array> </ListBox.ItemsSource> </ListBox> | cs |
ItemContainerStyleSelector속성에 셀렉터를 선언합니다.
실행해서 태스트해봅니다.
이처럼 셀렉터는 하나의 컨트롤에 여러 개의 템플릿이나 여러 개의 스타일을 함께 표현할 수 있게 해줍니다.
참고 : JERRIE PELSER > 3 Techniques you can use to make your data templates dynamic
'XAML 뽀개기' 카테고리의 다른 글
032. 데이터템플릿 & 트리거(DataTemplate & Trigger) #3 (0) | 2018.04.18 |
---|---|
031. 데이터템플릿 & 셀렉터(DataTemplate & Selector) #2 (0) | 2018.04.16 |
030. 데이타템플릿 & 컨버터(DataTemplate & Converter) #1 (0) | 2018.04.11 |
029. 툴팁 말풍선 슬라이더(ToolTip Balloon Slider) #3 (0) | 2018.04.09 |
028. 툴팁 말풍선 슬라이더(ToolTip Balloon Slider) #2 (0) | 2018.03.22 |
027. 툴팁 말풍선 슬라이더(ToolTip Balloon Slider) #1 (0) | 2018.03.20 |