변환기와 포맷팅
WPF 애플리케이션에서 데이터를 표현하는 경우, 값의 표현 방식을 상황에 맞게 유연하게 변경해야 할 때가 있습니다. 예를 들어, DataGrid에 표시되는 숫자 값을 10진수, 16진수, 또는 이진수로 동적으로 변환하여 보여주는 경우가 있습니다. 이를 효율적으로 구현하기 위해 값 변환기Value Converter를 사용할 수 있습니다.
변환기의 역할
IMultiValueConverter는 WPF에서 다중 바인딩MultiBinding을 처리할 때 사용하는 인터페이스입니다. 이 변환기를 사용하면 두 개 이상의 데이터를 결합하거나, 특정 로직에 따라 하나의 데이터로 변환하여 UI에 바인딩할 수 있습니다.
변환기 작성: 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
등).- 변환기ValueToDisplayConverter는
Value
와DisplayFormat
을 결합해 포맷에 맞는 문자열을 반환합니다.
결과 예제
예제 값
Value
:31
DisplayFormat
설정에 따른 결과
DisplayFormat | 결과 |
---|---|
Decimal | 31 |
Hex | 0x1F |
ByteBinary | 0001 1111 |
ShortBinary | 0000 0000 0001 1111 |
FullBinary | 0000 0000 0000 0000 0000 0000 0001 1111 |