-
WPF Converter (컨버터, 값 변환기)닷넷/WPF 2023. 6. 9. 15:06반응형
Converter
WPF에서 Converter는 WPF의 핵심 기능 중 하나인 데이터 바인딩에서 데이터를 바인딩하는 동안 값의 변환을 수행하는 데 사용되는 기능입니다. Converter를 사용하면 데이터를 원하는 형식으로 변환하거나, 값을 가공하여 UI 요소에 표시할 수 있습니다.
예를 들어, bool 값을 "예" 또는 "아니오"로 변환하거나, 숫자를 포맷팅하거나, 날짜 형식을 변경하는 등의 작업을 수행할 수 있습니다.
사용방법
Converter는 IValueConverter 또는 IMultiValueConverter 인터페이스를 구현하는 클래스로 작성됩니다. IValueConverter는 단일 값을 변환하는 데 쓰이며, IMultiValueConverter는 여러 값을 조합하여 변환하는 데 쓰입니다.
이 인터페이스에는 두 개의 메서드가 있습니다.
1. Convert
데이터 소스에서 UI 요소로 값이 전달될 때 호출되는 메서드입니다. 이 메서드는 변환된 값을 반환합니다. 예를 들어, 숫자를 문자열로 변환하거나, 날짜 형식을 변경하거나, 열거형 값을 텍스트로 변환하는 등의 작업을 수행할 수 있습니다.
2. ConvertBack
UI 요소에서 데이터 소스로 값이 전달될 때 호출되는 메서드입니다. 이 메서드는 다시 원래의 값으로 변환된 값을 반환합니다. 예를 들어, 문자열을 숫자로 변환하거나, 텍스트를 열거형 값으로 변환하는 등의 작업을 수행할 수 있습니다.
데이터 바인딩 표현식에서 Converter를 사용하여 데이터를 변환하는 방법은 다음과 같습니다.
<TextBlock Text="{Binding MyProperty, Converter={StaticResource MyConverter}}" />
위의 예시에서 "MyProperty"는 데이터 소스의 속성을 나타내며, "MyConverter"는 리소스로 선언된 Converter의 이름입니다. Converter는 데이터 소스로부터 값을 가져와서 필요한 변환 작업을 수행한 후에 UI 요소에 표시됩니다.
Converter 종류 및 코드 예시
어떤 것이든 IValueConverter 또는 IMultiValueConverter 인터페이스를 상속해서 직접 만들어도 되며, 몇 가지 일반적인 Converter의 종류는 다음과 같습니다.
1. BooleanConverter
논리값을 다른 형식으로 변환하는 데 사용됩니다. 예를 들어, true/false 값을 Yes/No 문자열로 변환하거나 Visibility로 변환하는 등의 작업을 수행할 수 있습니다.
<!-- Boolean 값을 "Yes" 또는 "No"로 변환하는 예시 --> <Window.Resources> <local:BooleanToYesNoConverter x:Key="BooleanToYesNoConverter" /> </Window.Resources> <TextBlock Text="{Binding IsEnabled, Converter={StaticResource BooleanToYesNoConverter}}" />
public class BooleanToYesNoConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is bool boolValue) { return boolValue ? "Yes" : "No"; } return value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException(); } }
<!-- Boolean 값을 컨트롤의 가시성을 뜻하는 Visibility 속성으로 변환하는 예시 --> <Window.Resources> <local:VisibilityConverter x:Key="VisibilityConverter" /> </Window.Resources> <Grid> <TextBlock Text="Hello, World!" Visibility="{Binding IsVisible, Converter={StaticResource VisibilityConverter}}" /> </Grid>
public class VisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is bool boolValue) { return boolValue ? Visibility.Visible : Visibility.Collapsed; } return Binding.DoNothing; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (value is Visibility visibilityValue) { return visibilityValue == Visibility.Visible; } return Binding.DoNothing; } }
2. StringConverter
문자열을 다른 형식으로 변환하는 데 사용됩니다. 예를 들어, 숫자를 문자열로 변환하거나, 문자열의 대소문자를 변경하는 등의 작업을 수행할 수 있습니다.
<!-- 숫자를 문자열로 변환하는 예시 --> <TextBlock Text="{Binding Quantity, Converter={StaticResource NumberToStringConverter}}" />
public class NumberToStringConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is int intValue) { return intValue.ToString(); } return value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException(); } }
3. DateTimeConverter
날짜와 시간을 다른 형식으로 변환하는 데 사용됩니다. 예를 들어, 날짜 형식을 변경하거나, 날짜와 시간 사이의 차이를 계산하는 등의 작업을 수행할 수 있습니다.
<!-- 날짜 형식을 변경하는 예시 --> <TextBlock Text="{Binding BirthDate, Converter={StaticResource DateTimeFormatConverter}, ConverterParameter='yyyy-MM-dd'}" />
public class DateTimeFormatConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is DateTime dateValue && parameter is string format) { return dateValue.ToString(format); } return value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException(); } }
4. EnumConverter
열거형 값을 다른 형식으로 변환하는 데 사용됩니다. 예를 들어, 열거형 값을 문자열로 변환하거나, 문자열을 열거형 값으로 변환하는 등의 작업을 수행할 수 있습니다.
<!-- 열거형 값을 문자열로 변환하는 예시 --> <TextBlock Text="{Binding Status, Converter={StaticResource EnumToStringConverter}}" />
public class EnumToStringConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is Enum enumValue) { return enumValue.ToString(); } return value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException(); } }
5. ColorConverter
색상을 다른 형식으로 변환하는 데 사용됩니다. 예를 들어, 색상을 RGB 값으로 변환하거나, RGB 값을 색상으로 변환하는 등의 작업을 수행할 수 있습니다.
<!-- SolidColorBrush를 Color로 변환하는 예시 --> <TextBlock Foreground="{Binding StatusColor, Converter={StaticResource SolidColorBrushToColorConverter}}" />
public class SolidColorBrushToColorConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is SolidColorBrush brush) { return brush.Color; } return value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException(); } }
6. ValueConverter
값의 형식을 변환하는 데 사용됩니다. 이는 가장 일반적으로 사용되는 Converter입니다. 예를 들어, 숫자를 포맷팅하거나, 값의 범위를 제한하는 등의 작업을 수행할 수 있습니다.
<!-- 숫자를 포맷팅하는 예시 --> <TextBlock Text="{Binding Price, Converter={StaticResource CurrencyConverter}}" />
public class CurrencyConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is decimal decimalValue) { return decimalValue.ToString("C", culture); // 통화 형식으로 변환 } return value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException(); } }
7. MultiValueConverter
여러 개의 값을 변환하는 데 사용됩니다. 여러 데이터 소스의 값을 조합하여 하나의 값으로 변환할 수 있습니다. 예를 들어, 두 숫자를 합치거나, 여러 개의 속성을 결합하여 문자열을 생성하는 등의 작업을 수행할 수 있습니다.
<!-- 두 개의 값을 합치는 예시 --> <TextBlock> <TextBlock.Text> <MultiBinding Converter="{StaticResource AdditionConverter}"> <Binding Path="Value1" /> <Binding Path="Value2" /> </MultiBinding> </TextBlock.Text> </TextBlock>
public class AdditionConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values.Length == 2 && values[0] is double value1 && values[1] is double value2) { return value1 + value2; } return Binding.DoNothing; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotSupportedException(); } }
8. DataTriggerConverter
데이터 바인딩 트리거에 사용되는 Converter입니다. 데이터 바인딩 값에 따라 UI 요소의 속성을 변경하는 데 사용됩니다. 예를 들어, 특정 조건에 따라 텍스트 색상을 변경하는 등의 작업을 수행할 수 있습니다.
<!-- 데이터 바인딩 값에 따라 텍스트 색상을 변경하는 예시 --> <TextBlock Text="{Binding Status}"> <TextBlock.Style> <Style TargetType="TextBlock"> <Setter Property="Foreground" Value="Black" /> <Style.Triggers> <DataTrigger Binding="{Binding Status}" Value="Complete"> <Setter Property="Foreground" Value="Green" /> </DataTrigger> <DataTrigger Binding="{Binding Status}" Value="Pending"> <Setter Property="Foreground" Value="Orange" /> </DataTrigger> <DataTrigger Binding="{Binding Status}" Value="Failed"> <Setter Property="Foreground" Value="Red" /> </DataTrigger> </Style.Triggers> </Style> </TextBlock.Style> </TextBlock>
9. MultiBindingConverter
여러 개의 데이터 바인딩을 처리하는 데 사용되는 Converter입니다. 여러 데이터 소스의 값을 조합하여 하나의 값으로 변환할 수 있습니다. 예를 들어, 두 숫자를 곱하거나, 여러 개의 속성을 결합하여 문자열을 생성하는 등의 작업을 수행할 수 있습니다.
<!-- 두 값을 곱하는 예시 --> <TextBlock> <TextBlock.Text> <MultiBinding Converter="{StaticResource MultiplicationConverter}"> <Binding Path="Value1" /> <Binding Path="Value2" /> </MultiBinding> </TextBlock.Text> </TextBlock>
public class MultiplicationConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values.Length == 2 && values[0] is double value1 && values[1] is double value2) { return value1 * value2; } return Binding.DoNothing; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotSupportedException(); } }
10. ImageConverter
이미지를 다른 형식으로 변환하는 데 사용됩니다. 예를 들어, 이미지를 바이트 배열로 변환하거나, 바이트 배열을 이미지로 변환하는 등의 작업을 수행할 수 있습니다.
<!-- 이미지를 바이트 배열로 변환하는 예시 --> <Window.Resources> <local:ImageConverter x:Key="ImageConverter" /> </Window.Resources>
<Image Source="{Binding Image, Converter={StaticResource ImageConverter}}" />
using System; using System.Globalization; using System.IO; using System.Windows.Data; using System.Windows.Media.Imaging; public class ImageConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { // 입력 값이 BitmapImage인지 확인 if (value is BitmapImage image) { // 이미지를 메모리 스트림으로 변환하여 바이트 배열로 가져오기 using (MemoryStream memoryStream = new MemoryStream()) { BitmapEncoder encoder = new PngBitmapEncoder(); // PNG 형식으로 인코딩 encoder.Frames.Add(BitmapFrame.Create(image)); // 이미지 프레임 추가 encoder.Save(memoryStream); // 스트림에 이미지 저장 return memoryStream.ToArray(); // 바이트 배열로 변환하여 반환 } } // 입력 값이 BitmapImage가 아닌 경우 Binding.DoNothing 반환 return Binding.DoNothing; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { // 이 컨버터에서는 역변환을 지원하지 않으므로 NotSupportedException 발생 throw new NotSupportedException(); } }
XAML에서 컨버터가 인식이 안 되는 경우
컨버터 클래스에 MarkupExtension을 추가로 상속하면 됩니다.
MarkupExtension
MarkupExtension은 XAML에서 사용되는 기능 중 하나로, XAML 마크업을 확장하고 커스터마이징하는 데 사용됩니다. MarkupExtension은 System.Windows.Markup 네임스페이스에 정의된 추상 클래스입니다.
MarkupExtension을 상속하는 클래스를 작성하여 사용자 정의 마크업 확장을 구현할 수 있습니다. 이 확장은 중괄호({}) 안에 특정 구문을 사용하여 XAML에서 값을 생성하거나 변환하는 작업을 수행할 수 있습니다. 예를 들어, 데이터 바인딩 설정, 리소스 참조, 다국어 지원 등 다양한 시나리오에서 MarkupExtension을 사용할 수 있습니다.
MarkupExtension을 상속한 클래스는 ProvideValue 메서드를 구현해야 합니다. 이 메서드는 XAML에서 확장을 사용할 때 호출되어 해당 확장이 반환해야 할 값을 제공합니다. ProvideValue 메서드에서는 필요한 로직을 수행하여 값을 생성하거나 변환할 수 있습니다.
사용자는 MarkupExtension을 상속하여 필요한 기능을 구현하고 XAML에서 사용할 수 있습니다. 이를 통해 XAML을 더 동적이고 유연하게 만들 수 있으며, 재사용 가능한 확장을 정의할 수 있습니다.
MarkupExtension 포함 코드 예시
일반적으로 컨버터를 XAML에서 사용하기 위해서는 컨버터 클래스가 IValueConverter 인터페이스를 구현하면 되지만, IValueConverter를 구현하는 단독 클래스는 XAML에서 직접적으로 인식되지 않을 수 있습니다. 이는 IValueConverter가 코드 레벨에서 작동하는 .NET Framework 구성 요소이기 때문입니다.
따라서 MarkupExtension를 상속하는 컨버터를 만들어 XAML에서 사용하면 XAML 런타임이 해당 컨버터를 인식하고 적절하게 처리할 수 있습니다.예를 들어, ValueConverterExtension라는 MarkupExtension를 상속하는 클래스를 작성하고, 해당 클래스를 사용하여 컨버터를 XAML에서 사용할 수 있습니다. 예시는 다음과 같습니다.
using System; using System.Globalization; using System.Windows; using System.Windows.Data; using System.Windows.Markup; public class ValueConverterExtension : MarkupExtension, IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { // 값을 변환하는 로직을 구현 // 예: 문자열을 대문자로 변환 if (value is string str) { return str.ToUpper(); } return value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { // 변환을 역으로 수행하는 로직을 구현 // 예: 대문자를 소문자로 변환 if (value is string str) { return str.ToLower(); } return value; } public override object ProvideValue(IServiceProvider serviceProvider) { return this; // 확장 자체를 반환 } }
반응형'닷넷 > WPF' 카테고리의 다른 글
WPF DevExpress 뷰가 로드될 때 특정 컨트롤(TextBox, TextEdit 등등)에 Focus 주는 방법 (0) 2024.04.01 C# WPF DataGrid에 Row번호 출력 되는 칼럼 추가하기 (닷넷프레임워크 .net framework 4.0 기준) (0) 2023.08.10 C# WPF에서 Binding(바인딩)이란? (0) 2023.04.07 C# WPF TextBlock이 렌더링 되지 않은 상태에서 ActualWidth 값이 계산되게 하는 방법 (0) 2023.03.28 C# WPF TextBlock의 Text를 오른쪽에서 왼쪽으로 애니메이션(BeginAnimation, 롤링) 하는방법 (0) 2023.03.21