프로그래밍/WPF

[WPF] 여러 Enum 상태에 따라 선택적으로 UserControl 표시하기

흔한티벳여우 2023. 4. 12. 14:36
반응형

 WPF에서 사용자 인터페이스를 개발하다 보면, 여러 상황에 따라 다양한 UserControl을 동적으로 표시해야 할 때가 있습니다. 이런 경우, Enum 상태에 따라 UserControl을 선택적으로 표시하는 방법을 사용할 수 있습니다. 

이 이번 포스팅에서는 DataTemplate 및 DataTemplateSelector를 사용하여 여러 Enum 상태에 따라 UserControl을 표시하는 방법을 알아봅니다.

 


1. Enum 정의

public enum Status
{
    First,
    Second,
    Third
}

2. 각 상태에 대한 UserControl 정의

 예를 들어, FirstControl.xaml, SecondControl.xaml, ThirdControl.xaml 파일을 각각 생성하여 다음과 같이 각 상태에 해당하는 UserControl을 정의합니다.

FirstControl.xaml

<UserControl x:Class="WpfApp1.FirstControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <TextBlock Text="First Control" FontWeight="Bold" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</UserControl>

SecondControl.xaml

<UserControl x:Class="WpfApp1.SecondControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <TextBlock Text="Second Control" FontWeight="Bold" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</UserControl>

ThirdControl.xaml

<UserControl x:Class="WpfApp1.ThirdControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <TextBlock Text="Third Control" FontWeight="Bold" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</UserControl>

 

3. Enum에 따라 UserControl을 선택하는 DataTemplateSelector 정의

using System.Windows;
using System.Windows.Controls;

public class StatusTemplateSelector : DataTemplateSelector
{
    public DataTemplate FirstTemplate { get; set; }
    public DataTemplate SecondTemplate { get; set; }
    public DataTemplate ThirdTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item is Status status)
        {
            switch (status)
            {
                case Status.First:
                    return FirstTemplate;
                case Status.Second:
                    return SecondTemplate;
                case Status.Third:
                    return ThirdTemplate;
                default:
                    return null;
            }
        }

        return null;
    }
}

 

4. 메인 Window XAML에서 DataTemplate 및 ContentControl 설정

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApp1"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate x:Key="FirstTemplate">
            <local:FirstControl/>
        </DataTemplate>
        <DataTemplate x:Key="SecondTemplate">
            <local:SecondControl/>
        </DataTemplate>
        <DataTemplate x:Key="ThirdTemplate">
            <local:ThirdControl/>
        </DataTemplate>
        <local:StatusTemplateSelector x:Key="StatusTemplateSelector"
                                       FirstTemplate="{StaticResource FirstTemplate}"
                                       SecondTemplate="{StaticResource SecondTemplate}"
                                       ThirdTemplate="{StaticResource ThirdTemplate}"/>
    </Window.Resources>
    <Grid>
        <ContentControl x:Name="statusContentControl" ContentTemplateSelector="{StaticResource StatusTemplateSelector}" Content="{Binding CurrentStatus}"/>
    </Grid>
</Window>

 

5. 메인 Window의 코드 비하인드에서 DataContext 설정 및 상태 변경 이벤트 추가

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;

namespace WpfApp1
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private Status _currentStatus;
        public Status CurrentStatus
        {
            get => _currentStatus;
            set
            {
                _currentStatus = value;
                OnPropertyChanged();
            }
        }

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;

            // 초기 상태 설정
            CurrentStatus = Status.First;

            // 테스트를 위해 상태 변경 이벤트 추가
            Loaded += (s, e) =>
            {
                DispatcherTimer timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
                timer.Tick += (sender, args) =>
                {
                    CurrentStatus = (Status)(((int)CurrentStatus + 1) % Enum.GetValues(typeof(Status)).Length);
                };
                timer.Start();
            };
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

이제 애플리케이션이 실행되면, 각 상태에 따라 UserControl이 자동으로 전환되는 것을 볼 수 있습니다. 이 예제에서는 간단한 타이머를 사용하여 CurrentStatus 속성을 변경하고 있지만, 실제 애플리케이션에서는 필요에 따라 상태 변경 로직을 구현할 수 있습니다. 예를 들어, 버튼 클릭 이벤트나 다른 사용자 인터페이스 요소와 상호작용을 통해 상태를 변경할 수 있습니다.

 


이 포스트에서는 WPF에서 여러 Enum 상태에 따라 UserControl을 선택적으로 표시하는 방법을 살펴보았습니다. DataTemplate 및 DataTemplateSelector를 사용하면 이러한 기능을 쉽게 구현할 수 있습니다. 이 방법을 사용하면, 애플리케이션의 사용자 인터페이스를 동적으로 관리하면서 코드의 가독성과 유지 관리성을 향상시킬 수 있습니다.

여러 상태에 따라 다양한 UserControl을 표시할 수 있으며, 각 상태와 관련된 로직을 해당 UserControl에 캡슐화하여 관리할 수 있습니다. 이렇게 함으로써 코드의 가독성과 유지 관리성을 향상시킬 수 있습니다.

또한 이 방법을 사용하면 애플리케이션의 사용자 인터페이스를 동적으로 구성하는 데 도움이 됩니다. 사용자 인터페이스 요소가 런타임에 변경되거나 추가되는 경우에도 쉽게 대응할 수 있습니다.

반응형