WPF Data Binding with IValueConverter

김정환(John.Kim)
OldbeeDev
Published in
5 min readNov 1, 2017
©geralt (pixabay)

Data Binding에서 Source와 Target의 Property 타입이 서로 다른 경우가 있다. 예를 들어 바인딩된 변수의 값에 따라 체크 박스를 표시해야 하는데, 이 변수가 Yes, No 등의 문자열이라면 체크 박스의 상태가 변경되지 않을 것이다. 체크 박스의 상태를 변경하려면 바인딩된 변수는 boolean 타입이어야 하기 때문이다. 이런 타입 불일치 문제를 해결해주는 것이 ValueConverter이다.

Concept

바인딩된 두 Property 사이에 타입 변환이 필요하면 Converter 객체를 만들어서 미들맨으로 끼워넣는다. Converter는 IValueConverter 인터페이스를 구현한 클래스로서 Convert() 메소드와 ConvertBack() 메소드를 구현해야 한다.

  • Convert()는 Source->Target 방향으로 변환이 필요할 때 호출된다.
  • ConvertBack()는 반대 방향으로 변환이 필요할 때 호출된다.

Implementation 예제

BoolToVisibilityConverter 클래스

예제로 사용할 BoolToVisibilityConverter 클래스는 이름 그대로 Boolean 타입의 값을 Visibility 타입으로 변환해주는 역할을 한다.

BoolToVisibilityConverter

BoolToVisibilityConverter 사용하기 #1

Converter의 namespace를 XAML namespace로 등록한다.

xmlns:local="clr-namespace:Project.Views"

Converter 리소스 객체를 생성하고 이름을 부여한다.

<Window.Resources>
<local:BoolToVisibilityConverter x:Key="Converter"/>
</Window.Resources>

Converter가 필요한 곳에서 StaticResource 구문으로 사용한다.

<CheckBox Content="Show Details" 
IsChecked="{Binding IsShowDetails}" />
<StackPanel Visibility="{Binding IsShowDetails,
Converter={StaticResource Converter}}">
<TextBlock Text="blah blah ..." />
</StackPanel>

ViewModel을 만들고, DataContext로 연결하는 등의 일련의 코드는 WPF Data Binding 문서를 참조하길 바란다.

그런데 Converter를 XAML에서 사용하는 방법이 좀 번거롭다. 리소스로 등록해야 하고, 이름도 지어줘야 하고, StaticResource로 불러줘야 한다. 이런 불편함은 MarkupExtension 클래스를 활용하면 해결할 수 있다.

BoolToVisiblityConverter 사용하기 #2

우선 BaseOnewayConverter 클래스를 먼저 만든다. 이 클래스는 OneWay 방향 ValueConverter를 위한 Base 클래스로서 MarkupExtension을 상속받고, IValueConverter를 구현한다.

BoolToVisibliltyConverter 클래스를 BaseOnewayConverter에서 상속받도록 수정한다. OneWay 변환만 필요하므로 Convert() 메소드만 override한다.

이렇게 수정된 Converter를 XAML에서 사용하는 방법은 아래와 같다.

<CheckBox Content="Show Details" 
IsChecked="{Binding IsShowDetails}" />
<StackPanel Visibility="{Binding IsShowDetails,
Converter={local:BoolToVisibilityConverter}}">
<TextBlock Text="blah blah ..." />
</StackPanel>

Converter를 리소스로 등록할 때 namespace를 이용해서 곧장 Converter 클래스를 사용함으로써 XAML 코드가 간결해졌다.

Wrapup :

Converter를 사용하지 않고 화면 표시에 필요한 Property를 모두 만들어서 바인딩만으로 화면 갱신을 할 수도 있다. 그러면 Behind-Code가 많아지고, Property 상태 관리도 복잡해지고, 버그도 많이 생기는 수순을 밟게 된다.

경험상, 단순한 상태 변경은 XAML에서 Converter로 구현하는 것이 코드도 직관적이고 버그도 줄어든다. 물론 너무 복잡한 Converter를 만들거나, 미묘하게 조금씩만 다른 Converter를 많이 만들면 동료를 힘들게 할 수도 있다.

References :

--

--