변환기와 포맷팅

변환기와 포맷팅

WPF 애플리케이션에서 데이터를 표현하는 경우, 값의 표현 방식을 상황에 맞게 유연하게 변경해야 할 때가 있습니다. 예를 들어, DataGrid에 표시되는 숫자 값을 10진수, 16진수, 또는 이진수로 동적으로 변환하여 보여주는 경우가 있습니다. 이를 효율적으로 구현하기 위해 값 변환기Value Converter를 사용할 수 있습니다.

변환기의 역할

IMultiValueConverter는 WPF에서 다중 바인딩MultiBinding을 처리할 때 사용하는 인터페이스입니다. 이 변환기를 사용하면 두 개 이상의 데이터를 결합하거나, 특정 로직에 따라 하나의 데이터로 변환하여 UI에 바인딩할 수 있습니다.

MultiValueConverter.png

변환기 작성: ValueToDisplayConverter

다음 예제는 다양한 숫자 포맷(10진수, 16진수, 8비트, 16비트, 32비트 이진수)을 지원하는 변환기입니다.

using System;
using System.Globalization;
using System.Linq;
using System.Windows.Data;
public class ValueToDisplayConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Length == 2 && values[1] is DisplayType displayType)
        {
            if (values[0] is IConvertible convertible)
            {
                var numericValue = convertible.ToInt64(CultureInfo.InvariantCulture); // 모든 숫자형 타입 처리
                return displayType switch
                {
                    DisplayType.Decimal => numericValue.ToString(),
                    DisplayType.Hex => $"0x{numericValue:X}",
                    DisplayType.ByteBinary => IntToBinaryString(numericValue, 8),
                    DisplayType.ShortBinary => IntToBinaryString(numericValue, 16),
                    DisplayType.FullBinary => IntToBinaryString(numericValue, 32),
                    _ => numericValue.ToString()
                };
            }
        }
        return values[0];
    }
    public object[]? ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return null; // 변환기에서는 역변환이 필요하지 않음
    }
    private string IntToBinaryString(long value, int bitCount)
    {
        char[] binary = new char[bitCount];
        for (int i = 0; i < bitCount; i++)
        {
            binary[bitCount - 1 - i] = ((value >> i) & 1) == 1 ? '1' : '0';
        }
        // 4자리씩 구분
        var result = new string(binary);
        return string.Join(" ", Enumerable.Range(0, bitCount / 4)
                                          .Select(i => result.Substring(i * 4, 4)));
    }
}

Enum 정의: DisplayType

숫자를 다양한 포맷으로 변환하기 위한 Enum입니다.

public enum DisplayType
{
    Decimal,       // 10진수
    Hex,           // 16진수
    ByteBinary,    // 8비트 이진수
    ShortBinary,   // 16비트 이진수        
    FullBinary     // 32비트 이진수
}

XAML에서 변환기 등록

변환기를 XAML에서 사용하려면 리소스로 등록해야 합니다. ValueToDisplayConverter를 리소스에 추가합니다.

<UserControl.Resources>
    <local:ValueToDisplayConverter x:Key="ValueToDisplayConverter" />
</UserControl.Resources>

전역으로 사용하는 경우, app.xaml에 등록할 수 있습니다.

<Application.Resources>        
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>           
            ...
        </ResourceDictionary.MergedDictionaries>
        <local:ValueToDisplayConverter x:Key="ValueToDisplayConverter" />
    </ResourceDictionary>
</Application.Resources>

DataGrid에 적용

MultiBinding을 사용하여 DataGrid에 숫자 값을 표시할 때 변환기를 활용합니다.

<DataGridTemplateColumn Header="Value">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock>
                <TextBlock.Text>
                    <MultiBinding Converter="{StaticResource ValueToDisplayConverter}">
                        <Binding Path="Value" />
                        <Binding Path="DisplayFormat" />
                    </MultiBinding>
                </TextBlock.Text>
            </TextBlock>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

ViewModel 구성

ViewModel에서 데이터의 표시 형식을 동적으로 변경하기 위해 DisplayFormat 속성을 추가합니다.

private DisplayType _displayFormat = DisplayType.Decimal;
public DisplayType DisplayFormat
{
    get => _displayFormat;
    set
    {
        _displayFormat = value;
        OnPropertyChanged(nameof(DisplayFormat));
    }
}
private int _value;
public int Value
{
    get => _value;
    set
    {
        _value = value;
        OnPropertyChanged(nameof(Value));
    }
}

전체 코드 흐름

  • Value: DataGrid에 표시될 숫자 값.
  • DisplayFormat: 숫자를 표시할 포맷(Decimal, Hex, Binary 등).
  • 변환기ValueToDisplayConverterValueDisplayFormat을 결합해 포맷에 맞는 문자열을 반환합니다.

결과 예제

예제 값

  • Value: 31

DisplayFormat 설정에 따른 결과

DisplayFormat결과
Decimal31
Hex0x1F
ByteBinary0001 1111
ShortBinary0000 0000 0001 1111
FullBinary0000 0000 0000 0000 0000 0000 0001 1111