티스토리 뷰
일반적인 데이터 바인딩은 다음과 같다.
소스에서 타겟으로 또는 타겟에서 소스로 객체가 가지고 있는 속성 및 데이터를 매핑시켜줄 수 있다.
하지만, 바인딩한 데이터가 서로 다른 타입인 경우 어떻게 될까?
서로 다른 타입을 바인딩하려는 경우 정상적으로 데이터를 화면에 보여줄 수 없다.
이때 사용하는 것이 ValueConverter(값 변환기)이다.
데이터 바인딩을 진행하면서
Value Converter는 값 변환을 진행한다. 이는 사용자가 직접 형변환 코드를 삽입하거나
조건을 새롭게 만들어 특정 조건에만 특정 값을 바인딩할 수 있게 할 수도 있다.
ValueConvereter 클래스를 생성할 때 이름은 <SourceType>To<TargetType>으로 사용하는 것이 일반적인 네이밍이다.
먼저 ValueConverter를 어떻게 구현 및 사용하는지 살펴보자.
1. ValueConverter 클래스 생성 및 IValueConvereter 인터페이스 상속
2. IConverter 인터페이스에 정의된 메소드 IDE자동완성을 통한 구현 (Convert, ConvertBack 메소드)
3. xaml에서 사용할 수 있도록 객체 등록 (BaseValueConveter 생성, MarkupExtension 상속)
4. Convert, ConvertBack 코드 작성
기본적인 문법만 알면 크게 어려울 것이 없다.
가장 중요한 것이 xaml에서 사용할 수 있도록 객체를 등록하는 것인데
이때 사용하는 것이 가장 최상위가 되는 BaseConvereter를 생성해서 MarkupExtension을 상속받는 것이다.
이 상속은 다른 인터페이스 상속보다 우선되어야 한다.
BaseConveter 클래스가 MarkupExtension을 상속 받으면 ProvideValue 함수를 override하여 재정의한다.
BaseValueConveter를 상속받은 객체를 반환하는 것이 목적이므로 this를 반환한다.
namespace WPF_ValueConverterTest
{
public class BaseValueConverter : MarkupExtension
{
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
}
이제 새로운 ValueConveter를 생성해서 사용하는 경우 BaseValueConvereter 클래스만 상속받아
IValueConveter 인터페이스를 구현하면 xaml에서도 사용할 수 있다.
xaml에서는 다음과 같이 사용한다.
local:은 xlmns:local로 선언한 현재 프로젝트의 기본 네임스페이스이다.
중요하게 봐야할 건 xaml에서의 Convereter를 사용하는 방법도 있지만,
Visibility 속성을 DatePciker_에 바인딩하여 선택된 날짜(SelectedDate)의 일수가 짝수인 경우에만 보여주는 것이다.
Target인 TextBlock객체의 Visibility 속성 값 타입과 Source인 DatePicker객체의 SelectedDate 속성 값 타입이 서로 다르지만ShowConverter로 인해 자연스레 작동할 수 있게 되는 것이다.
<DatePicker x:Name="DatePicker_" DisplayDate="{x:Static sys:DateTime.Now}"/>
<TextBlock x:Name="DateText"
Visibility="{Binding Mode=OneWay,
ElementName=DatePicker_,
Path=SelectedDate,
Converter={local:ShowConverter}}"
Text="{Binding ElementName=DatePicker_, Path=SelectedDate, StringFormat='선택한 날짜는 yyyy년 MM월 dd일'}"/>
ShowConvereter 코드이다.
ValueConversion으로 특성을 등록하는 것은 잊지말자.
매개변수 value에서 바인딩 Path 정보인 SelectedDate 데이터가 매개변수로 들어오게 되면 연산이 필요한 경우
이 값을 활용하고 마지막으로 Visibility Type으로 반환한다.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
namespace WPF_ValueConverterTest
{
[ValueConversion(typeof(DateTime), typeof(Visibility))]
class ShowConverter : BaseValueConverter, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null)
{
DateTime dt;
if(DateTime.TryParse(value.ToString(), out dt) == true)
{
if (dt.Day % 2 == 0)
{
return Visibility.Hidden;
}
}
}
return Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
}
SourceType, TargetType을 정의하는 건 ValueConversion 특성 등록할 때 사용된다.
Convert 메소드는 SourceType에 일치하는 데이터 타입이 매개변수(value)로 넘어온 경우 호출되고
반대로 ConverBack 메소드는 TargetType에 일치하는 데이터 타입이 매개변수(value)로 넘어온 경우 호출된다.
작동되는 모습을 살펴보자
이 밖에도 ValueConvereter를 이용하면 IsEnabled, IsReadOnly 등 다양한 방법으로 활용될 수 있다.