GSI

'IValueConverter'에 해당되는 글 1건

  1. 2007.11.22 데이터 바인딩#6 - IValueConverter

데이터 바인딩#1 - 기본
데이터 바인딩#2 - Binding Mode
데이터바인딩#3 - DataContext
데이터 바인딩#4 - TextBox vs Run
데이터 바인딩#5 - FrameWorkElement Demo
데이터 바인딩#6 - IValueConverter


이번 시간에는 변환에 대해서 알아 보겠습니다. 데이터 바인딩을 하다 보면 간혹 다른 타입의 데이터를 변환해서 사용해야 하는 경우가 발생합니다. 칼라 값을 변환해서 사용한다던지 아니면 실수형 데이터를 정수형 데이터로 변환해서 사용한다던지 하는 과정을 처리 해야 하는데요 이때 사용할 수 있는 것이 IValueConverter 인터페이스 입니다.

변환을 수행하는 클래스를 제작할때 반드시 IValueConverter 인터페이스를 구현해야 합니다.
그 형태는 아래와 같습니다.

public class MyConverter : IValueConverter
{
   public object Convert(object value, Type typeTarget,
                                                  object param, CultureInfo culture)
   {
      ...
   }

   public object ConvertBack(object value, Type typeTarget,
                                                    object param, CultureInfo culture)
   {
      ...
   }
}

value 인자는 변환될 객체이고 typeTarget는 변환될 객체의 타입입니다.
세번재 인자인 param은 Binding할때 ConvertParameter 프로퍼티가 명시한 객체가 들어가게 됩니다. 그리고 마지막 객체는 대부분 무시 됩니다.

그리고 변환을 위해서는 Convert, ConvertBack 두개가 반드시 필요 합니다.

C#에서는 아래와 같이 수행할 수 있습니다.
Binding bind = new Binding(); bind.Convert = new MyConverter();


아래의 코드는 Convert의 내용입니다.

    [ValueConversion(typeof(double), typeof(decimal))]
    class DoubleToDecimalConverter : IValueConverter
    {
        public object Convert(object value, Type typeTarget, object param, CultureInfo culture)
        {
            decimal num = new decimal((double)value);

            if (param != null)
                num = Decimal.Round(num, Int32.Parse(param as string));

            return num;
        }

        public object ConvertBack(object value, Type typeTarget, object param, CultureInfo culture)
        {
            return Decimal.ToDouble((decimal)value);
        }
    }

여기서 보시면 위쪽의 [ValueConversion(typeof(double), typeof(decimal))] 의 내용은 사실상 없어도 에러가 나거나 하지는 않습니다. 하지만 WPF 문서에서 보게 되면 이 구문을 클래스 정의의 바로 밑에 포함하게 권고 하고 있습니다. 제가 봐도 들어가 있을때 가독성 부분에서는 조금더 유연해 지지 않을까 생각 됩니다.

Convert를 xaml 코드에 연동하는 부분은 이전 강좌의 소스 코드 부분에 바로 적용해봤습니다.

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:src="clr-namespace:WpfApplication1"
    Title="Window1" Height="300" Width="300">

    <Window.Resources>
        <src:DoubleToDecimalConverter x:Key="conv" />
    </Window.Resources>

    <StackPanel>
        <ScrollBar  Orientation="Horizontal"
                    Margin="24"
                    Maximum="100"
                    LargeChange="10"
                    SmallChange="1"
                    Value="{Binding ElementName=Simple, Path=Number, Mode=OneWayToSource}" />
       
        <src:SimpleElement x:Name="Simple" HorizontalAlignment="Center" />
       
        <ScrollBar  Name="scroll"
                    Orientation="Horizontal"
                    Margin="24"
                    Maximum="100"
                    LargeChange="10"
                    SmallChange="1"
                    Value="{Binding ElementName=Simple, Path=Number, Mode=OneWay}" Height="17" />
       
        <src:SimpleElement HorizontalAlignment="Center" Number="{Binding ElementName=scroll, Path=Value, Mode=OneWay, Converter={StaticResource conv}, ConverterParameter=2}" Height="50" />
    </StackPanel>
</Window>

xaml 코드에서는 위에서와 같이 Resource에서 IValueConverter를 구현하는 클래스를 명시해 주어야 합니다.
그리고 Binding 정의에서는 위에서와 같이 Converter={StaticResource conv}, ConverterParameter=2 를 해주시게 되면 됩니다.

추가적으로 public의 프로퍼티가 있을 경우 값을 추가한 후에 정보 전달도 가능합니다.
<src:DoubleToDecimalConverter Decimals="4" x:Key="conv" />
(Decimals 라는 public 프로퍼티가 선언되어 있다고 가정할때)

위의 코드의 결과는 이전의 강좌에서 소수점으로 쫙 나열되어 있는 정보를 소수 둘째 자리까지 자른후에 표시 할 수 있는 코드 입니다. ^^

그럼.. 오늘 강좌는 여기까지 ^^..
다음 강좌는 MultiBinding를 작성하도록 하겠습니다.

참고 ^^
본 내용은 "찰스페졸드의 WPF"의 내용을 이해 하고 나름 생각과 같이 정리한 겁니다.
제제가 가해질 경우 바로 삭제하도록 하겠습니다. ^^;
Posted by gsi
: