다음은 간단한 도메인 모델 클래스입니다:
**요구사항 1: 버튼 클릭 시 Person 인스턴스의 이름을 표시**
이를 구현하기 위해 XAML에서 리소스로 객체를 정의합니다:
버튼 이벤트 처리기 코드:
**요구사항 2: 자식 객체의 이름을 표시하려면**
다음과 같이 XAML에 `Spouse` 속성에 문자열 값을 할당하려고 합니다:
하지만 이는 컴파일 오류를 발생시킵니다. 왜냐하면 `Spouse` 속성은 `Person` 타입이지만, `Spouse="Bob"`은 문자열이기 때문입니다. WPF에서는 이러한 타입 불일치를 해결하기 위해 **TypeConverter** 기능을 제공합니다.
### TypeConverter 개요
`System.ComponentModel.TypeConverter`는 문자열과 다른 형식 간의 변환을 정의할 수 있게 해주는 핵심 클래스입니다. 주요 역할은 다음과 같습니다:
- **문자열 → 특정 타입**: XAML 파서가 속성에 문자열 값을 지정했을 때, 이를 해당 타입으로 변환하는 데 사용됩니다.
- **특정 타입 → 문자열**: 디자인 타임 또는 디버깅 시 값의 표현을 위한 용도로 사용됩니다.
### 컨버터 구현 단계
1. `TypeConverter`를 상속받아 커스텀 변환기 작성
2. `CanConvertFrom`, `CanConvertTo` 메서드 재정의
3. `ConvertFrom` 및 `ConvertTo` 메서드 구현
4. 대상 클래스에 `TypeConverterAttribute` 적용
### 커스텀 변환기 작성
`Spouse` 속성에 문자열을 입력하면 `Person` 인스턴스로 변환하도록 정의합니다:
이제 XAML에서 다음과 같이 문자열을 직접 설정할 수 있습니다:
변환기가 자동으로 `"Charlie"`라는 문자열을 `Person` 인스턴스로 변환하므로, 실행 시 정상적으로 동작하며 `MessageBox`에 `Charlie`가 표시됩니다.
이 방식은 복잡한 그래프 구조를 포함한 객체 트리를 선언적 방식으로 구성할 때 매우 유용합니다.
코드 보기
public class Person
{
public string FullName { get; set; }
public Person Spouse { get; set; }
}
코드 보기
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp"
Title="Person Viewer" Height="300" Width="400">
<Window.Resources>
<local:Person x:Key="person" FullName="Alice" />
</Window.Resources>
<Grid>
<Button Content="Show Name" Click="OnShowClick" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</Window>
코드 보기
private void OnShowClick(object sender, RoutedEventArgs e)
{
var person = this.FindResource("person") as Person;
if (person != null)
{
MessageBox.Show(person.Spouse?.FullName ?? "No spouse");
}
}
코드 보기
<local:Person x:Key="person" FullName="Alice" Spouse="Bob" />
코드 보기
[TypeConverter(typeof(NameToPersonConverter))]
public class Person
{
public string FullName { get; set; }
public Person Spouse { get; set; }
}
public class NameToPersonConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
{
return sourceType == typeof(string);
}
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
if (value is string name && !string.IsNullOrWhiteSpace(name))
{
return new Person { FullName = name };
}
return base.ConvertFrom(context, culture, value);
}
}
코드 보기
<local:Person x:Key="person" FullName="Alice" Spouse="Charlie" />