본문 바로가기
Languages/C#

Day 16: ControlTemplate(컨트롤 템플릿) 커스터마이징, DataTemplate

by 반도체는 프로그래밍을 좋아해 2023. 4. 20.
728x90

Day 16: 컨트롤 템플릿 커스터마이징

WPF에서는 컨트롤의 표시 방식을 변경할 수 있는 템플릿을 제공합니다. 이러한 템플릿은 ControlTemplate과 DataTemplate 두 가지가 있으며, 컨트롤의 종류에 따라 적용할 수 있는 템플릿이 다릅니다.

ControlTemplate은 컨트롤의 룩앤필(Look and Feel)을 변경하는 템플릿입니다. 일반적으로 컨트롤의 배경, 테두리, 텍스트 등을 포함한 모든 시각적인 요소를 변경할 수 있습니다.

DataTemplate은 컨트롤의 데이터 표시 방식을 변경하는 템플릿입니다. 예를 들어 ListBox에 바인딩되는 데이터가 객체의 리스트인 경우, DataTemplate을 사용하여 각각의 항목을 어떻게 표시할지 정의할 수 있습니다.

컨트롤의 템플릿을 커스터마이징하는 것은 WPF에서 강력한 UI 디자인을 가능케 합니다. 아래는 반도체 제조공정의 이미지를 보여주는 Image 컨트롤에 대해 커스텀 템플릿을 적용하는 예시입니다.

<Window.Resources>
    <ControlTemplate x:Key="MyImageTemplate" TargetType="Image">
        <Grid>
            <Image Source="{TemplateBinding Source}" Stretch="None" />
            <Ellipse Width="20" Height="20" Fill="Green" Margin="5" VerticalAlignment="Top" HorizontalAlignment="Left" />
            <Ellipse Width="20" Height="20" Fill="Red" Margin="5" VerticalAlignment="Top" HorizontalAlignment="Right" />
            <Ellipse Width="20" Height="20" Fill="Blue" Margin="5" VerticalAlignment="Bottom" HorizontalAlignment="Left" />
            <Ellipse Width="20" Height="20" Fill="Yellow" Margin="5" VerticalAlignment="Bottom" HorizontalAlignment="Right" />
        </Grid>
    </ControlTemplate>
</Window.Resources>

위의 코드에서는 ControlTemplate을 정의하고, Image 컨트롤에 적용할 수 있도록 x:Key 속성을 이용해 템플릿을 식별합니다.

<Image Source="semiconductor.png" Template="{StaticResource MyImageTemplate}" />

위의 코드에서는 Image 컨트롤에 Source 속성을 이용해 이미지 파일을 로드하고, Template 속성을 이용해 MyImageTemplate 템플릿을 적용합니다.

728x90

다음은 DataTemplate 예제입니다.

DataTemplate을 사용하여 ListView의 각 항목을 표시하는 방식을 변경하는 예시를 살펴보겠습니다. 예를 들어, 반도체 제조 업체에서 생산되는 반도체 칩의 리스트를 표시하는 애플리케이션이 있다고 가정해 봅시다.

기본적으로는 각 항목이 반도체 칩의 이름과 설명만 포함하고 있습니다. 하지만, 해당 업체에서는 칩의 등급에 따라 다른 아이콘을 표시하고 싶다는 요구사항이 있습니다. 이때 DataTemplate을 사용하여 이를 구현할 수 있습니다.

먼저, 기본적인 ListView를 만들어 봅시다. XAML에서 다음과 같이 작성할 수 있습니다.

<ListView ItemsSource="{Binding Chips}">
  <ListView.Resources>
    <local:ImageConverter x:Key="imageConverter" />
  </ListView.Resources>
  <ListView.ItemTemplate>
    <DataTemplate>
      <StackPanel Orientation="Horizontal">
        <Image Source="{Binding Grade, Converter={StaticResource imageConverter}}" />
        <StackPanel>
          <TextBlock Text="{Binding Name}" />
          <TextBlock Text="{Binding Description}" />
        </StackPanel>
      </StackPanel>
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

위의 예제에서는 ListView가 Chips라는 ObservableCollection을 바인딩하고 있으며, 각 항목은 DataTemplate 내에서 StackPanel을 사용하여 텍스트 블록으로 구성됩니다.

이제 등급에 따라 다른 아이콘을 표시하도록 DataTemplate을 수정해 봅시다. 먼저, 등급에 따라 다른 아이콘을 표시하는 ImageConverter 클래스를 만들어야 합니다. 이 클래스는 IValueConverter 인터페이스를 구현하여 등급을 기반으로 이미지 경로를 반환합니다.

public class ImageConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
    string grade = value as string;
    if (grade == "A")
      return "/Images/GradeA.png";
    else if (grade == "B")
      return "/Images/GradeB.png";
    else
      return "/Images/GradeC.png";
  }

  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  {
    throw new NotImplementedException();
  }
}

위의 예제에서는 ImageConverter 클래스를 ListView의 리소스로 추가하고 있으며, 등급에 따라 다른 아이콘을 표시하기 위해 Image 컨트롤을 추가하였습니다. DataTemplate은 이제 StackPanel안에 배치된 두 개의 TextBlock과 Image 컨트롤로 구성되며, 이를 통해 리스트뷰 아이템에 대한 디자인을 구성하고 있습니다.


이처럼 WPF에서는 다양한 방식으로 데이터를 시각적으로 표현할 수 있도록 지원하고 있습니다. DataTemplate을 사용하여 데이터의 표현 방식을 커스터마이징하면, 간단한 UI 요소들로도 다양한 형태의 데이터를 시각적으로 표현할 수 있습니다. 이를 통해 사용자에게 보다 직관적이고 유용한 정보를 제공할 수 있게 됩니다.

ControlTemplate을 사용하여 배경, 테두리, 그림자 등의 속성을 변경하거나 DataTemplate을 사용하여 데이터를 표시하는 방식을 변경할 수 있습니다. 이를 통해 개발자는 기존의 컨트롤의 모양이나 동작을 유지하면서도 자신이 원하는 디자인과 데이터 표시 방식으로 변경할 수 있습니다. 이러한 기능은 WPF를 사용하여 UI를 개발할 때 유용하게 활용됩니다.

또 다른예시를 들어 설명해보겠습니다.

반도체 공정 관련 애플리케이션을 예시로 들어보면, 공정 상황에 따라 다양한 데이터를 실시간으로 확인해야 합니다. 이때, 커스텀 컨트롤을 이용하여 다양한 데이터를 표시할 수 있습니다. 예를 들어, 반도체 칩의 검사 결과를 표시하는데 사용되는 ListView를 커스터마이징하여, 칩의 크기, 모양 등에 따라 색상이나 아이콘으로 표시할 수 있습니다.

또는 반도체 공정에서 발생하는 데이터의 추이를 표시하는 Line Chart나 Bar Chart 같은 차트 컨트롤을 커스터마이징하여, 사용자가 쉽게 데이터를 파악할 수 있도록 표시할 수도 있습니다. 

다음은 반도체 칩 검사 결과를 표시하는 ListView를 커스터마이징하는 예제입니다. ListView의 ItemTemplate 속성을 DataTemplate으로 지정하여, 칩의 검사 결과를 색상으로 표시합니다.

<ListView ItemsSource="{Binding Chips}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Rectangle Fill="{Binding Result, Converter={StaticResource ResultToColorConverter}}" Width="30" Height="30"/>
                <TextBlock Text="{Binding Name}" Margin="10,0,0,0"/>
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

위 코드에서, ResultToColorConverter는 검사 결과 값을 색상으로 변환해주는 Converter 클래스입니다. 이 Converter를 ListView의 리소스로 추가해줘야 합니다.

<ListView.Resources>
    <local:ResultToColorConverter x:Key="ResultToColorConverter"/>
</ListView.Resources>

이제, 칩의 검사 결과에 따라 다른 색상으로 표시됩니다.

해당 ResultToColorConverter의 내용은 아래와 같습니다.

public class ResultToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return null;

        // 검사 결과 값에 따라 적절한 색상 반환
        if (value.ToString() == "Pass")
            return new SolidColorBrush(Colors.Green);
        else if (value.ToString() == "Fail")
            return new SolidColorBrush(Colors.Red);
        else
            return new SolidColorBrush(Colors.Yellow);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

/*
public interface IValueConverter
{
    object Convert(object value, Type targetType, object parameter, CultureInfo culture);

    object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
}
*/

다음은 반도체 공정에서 발생하는 데이터의 추이를 표시하는 Line Chart를 커스터마이징하는 예제입니다.

 Chart의 SeriesTemplate 속성을 DataTemplate으로 지정하여, 데이터의 시간대별 추이를 선으로 표시합니다.

차트에 대한 설명은 추후에 다른 post에서 진행하겠습니다.

<chartingToolkit:Chart Title="Data Trend" LegendTitle="Legend">
    <chartingToolkit:Chart.Series>
        <chartingToolkit:LineSeries ItemsSource="{Binding Data}" 
                                     IndependentValueBinding="{Binding Time}" 
                                     DependentValueBinding="{Binding Value}">
            <chartingToolkit:LineSeries.DataPointStyle>
                <Style TargetType="{x:Type chartingToolkit:LineDataPoint}">
                    <Setter Property="Width" Value="10"/>
                    <Setter Property="Height" Value="10"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type chartingToolkit:LineDataPoint}">
                                <Ellipse Fill="{Binding Converter={StaticResource ValueToColorConverter}}"/>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </chartingToolkit:LineSeries.DataPointStyle>
        </chartingToolkit:LineSeries>
    </chartingToolkit:Chart.Series>
</chartingToolkit:Chart>

위 코드에서, ValueToColorConverter는 데이터 값을 색상으로 변환해주는 Converter 클래스입니다. 이 Converter를 Chart의 리소스로 추가해줘야 합니다.

<chartingToolkit:Chart.Resources>
    <local:ValueToColorConverter x:Key="ValueToColorConverter"/>
</chartingToolkit:Chart.Resources>

이제, 데이터의 추이에 따라 다른 색상으로 표시됩니다.

해당 ValueToColorConverter의 내용은 아래와 같습니다.

public class ValueToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // 입력된 값을 double 형식으로 변환합니다.
        double inputValue = System.Convert.ToDouble(value);

        // 입력된 값에 따라서 적절한 색상을 반환합니다.
        if (inputValue < 50)
        {
            return new SolidColorBrush(Colors.Blue);
        }
        else if (inputValue < 100)
        {
            return new SolidColorBrush(Colors.Green);
        }
        else
        {
            return new SolidColorBrush(Colors.Red);
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
    
/*
public interface IValueConverter
{
    object Convert(object value, Type targetType, object parameter, CultureInfo culture);

    object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
}
*/

컨트롤 템플릿과 데이터 템플릿을 이용하여 WPF 애플리케이션에서 컨트롤을 커스터마이징하는 방법에 대해 살펴보았습니다. 이를 이용하면 다양한 애플리케이션에서 사용자 정의 컨트롤을 만들고, 데이터를 표시하는 방법을 변경할 수 있습니다.

반도체 공정 관련 애플리케이션 예시를 통해, ListView와 Chart 컨트롤을 커스터마이징하는 방법을 살펴보았습니다. 이러한 방식을 이용하여 반도체 공정에서 발생하는 다양한 데이터를 실시간으로 표시하거나, 분석할 수 있습니다.

WPF에서는 다양한 컨트롤을 제공하고 있으며, 이러한 컨트롤들을 이용하여 UI를 구성할 수 있습니다. 또한 컨트롤 템플릿과 데이터 템플릿을 이용하여, 이러한 기본적인 컨트롤들을 커스터마이징하여 보다 다양하고 유연한 UI를 구현할 수 있습니다.

 

728x90