데이터 바인딩 4

바인딩 Source로 정적 객체와 연결

Binding Source 속성을 이용해 DataContext 이외의 객체와 멤버를 Binding 할 때, 사용한다.

<Window x:Class="BindingDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:BindingDemo"
        Title="BindingDemo" Height="171" Width="230" DataContext="{Binding}">
    <Canvas>
        <TextBox Canvas.Left="29" Canvas.Top="30" Height="24" Width="99" Text= "{Binding TextName, Source={x:Static local:TestClass.Object}}"/>
        <Button Canvas.Left="32" Canvas.Top="80" Content="Button" Height="23" Name="button1" Width="129" Click="Button_Click" />
    </Canvas>
</Window>

xmlns:local="clr-namespace:BindingDemo" 

다른 객체를 참고 하기 위한 네임스페이스를 지정한다.

Text= "{Binding TextName, Source={x:Static local:TestClass.Object}}"

Binding 할 속성은 TextName이다. Source로 객체를 지정한다.
정적인 객체는 {x:Static 객체} 와 같이 지정한다. local은 미리 선언한 clr-namespace이다.

namespace BindingDemo
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {
         public MainWindow()
        {
            InitializeComponent();

             this.DataContext = this;
        }

         private void Button_Click(object sender, RoutedEventArgs e)
         {
             MessageBox.Show(TestClass.Object.TextName);
         }
    }

    public class TestClass
    {
        private static TestClass Instance = new TestClass();
        public static TestClass Object { get { return Instance; } }

        public string TextName { get; set; }

        private TestClass()
        {
        }
    }
}

정적 멤버로 선언된 TestClass의 TextName 속성을 이용하고 있다.
실행화면이다.

다운로드 : BindingDemo_source_static.zip

 

Binding Converter 이용

Converter를 이용하여 Binding 소스의 값을 새로운 형식으로 변환한다.
이번 예제에서는 10진수를 입력하면 TextBlock으로 16진수로 변환된 문자열을 출력 한다.

<Window x:Class="BindingDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:BindingDemo"
        Title="BindingDemo" Height="171" Width="230" DataContext="{Binding}">
    <Window.Resources>
        <local:HexConverter x:Key="HexConv"/>
    </Window.Resources>
    <Canvas>
        <TextBox Text="{Binding TestValue, UpdateSourceTrigger=PropertyChanged}"
             Width="70" Height="23" Margin="5"
             HorizontalAlignment="Left" VerticalAlignment="Top"/>
        <TextBlock Text="{Binding TestValue, Converter={StaticResource HexConv}}"
               Grid.Row="1" Width="146" Height="23" Margin="5"
               HorizontalAlignment="Left" VerticalAlignment="Top" Canvas.Left="0" Canvas.Top="44" />
    </Canvas>
</Window>

<local:HexConverter x:Key="HexConv"/>

CS 코드에 있는 HexConverter를 자원 등록하고 있다.

Text="{Binding TestValue, UpdateSourceTrigger=PropertyChanged}"

TextBox값이 바뀌면 즉시, TestValue 값도 바뀌도록 한다.

Text="{Binding TestValue, Converter={StaticResource HexConv}}"

TextBlock의 Binding에서 Converter를 설정하고 있다.
HexConv에 의해 16진수로 변환한다.

using System.ComponentModel;

namespace BindingDemo
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private int val;
        public int TestValue
        {
            get { return val; }
            set
            {
                val = value;
                OnPropertyChanged("TestValue");
            }
        }

        public MainWindow()
        {
            InitializeComponent();

             this.DataContext = this;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
    }

    public class HexConverter : IValueConverter
    {
        public object Convert(object value, Type type, object parameter, System.Globalization.CultureInfo culture)
        {
            int v = (int)value;
            return string.Format("0x{0:X2}", v);
        }

        public object ConvertBack(object value, Type type, object parameter, System.Globalization.CultureInfo culture)
        {
            string s = (string)value;
            int v;
            if (int.TryParse(s, System.Globalization.NumberStyles.AllowHexSpecifier, null, out v))
            {
                return v;
            }
            return 0;
        }
    }
}

16진수로 변환하는 HexConverter를 정의하고 있다.

Binding의 Converter에 지정된 클래스는 IValueConverter 인터페이스를 상속해서 구현한다.
IValueConverter는 Convert, ConvertBack의 두가지 방법이 있다.

Convert가 Binding 소스 컨트롤에 데이터 전달시에 호출되는 반환
ConvertBack은 반대의 경우 호출되는 변환이다.

다운로드 : BindingDemo_convert.zip

 

< 에러 대처 >

BindingDemo_convert.zip의 경우 압축을 풀면 아래와 같은 에러가 발생 할것이다.

빌드 관련 모든 데이터를 삭제하면 다음과 같은 에러가 발생 할 수도 있다.
다시 빌드하면 해결되는 경우도 있다.

정의되지 않은 CLR 네임스페이스입니다. 'clr-namespace' URI는 어셈블리에 포함되지 않은 'BindingDemo' 네임스페이스를 참조합니다.

'local:HexConverter' 형식이 없습니다. 어셈블리 참조가 있는지, 그리고 참조된 모든 어셈블리가 빌드되었는지 확인하십시오.

 

Binding ConverterParameter 속성 이용

ConverterParamter를 이용하여 값을 변환 클래스로 매개 변수를 전달할 수도 있다.

<Canvas>
    <TextBox Text="{Binding TestValue, UpdateSourceTrigger=PropertyChanged}"
         Width="70" Height="23" Margin="5"
         HorizontalAlignment="Left" VerticalAlignment="Top"/>
    <TextBlock Text="{Binding TestValue, Converter={StaticResource HexConv}, ConverterParameter = 6}"
           Grid.Row="1" Width="146" Height="23" Margin="5"
           HorizontalAlignment="Left" VerticalAlignment="Top" Canvas.Left="0" Canvas.Top="44" />
</Canvas>

Text="{Binding TestValue, Converter={StaticResource HexConv}, ConverterParameter = 6}"

ConverterParameter 값을 6으로 지정한다.

public object Convert(object value, Type type, object parameter, System.Globalization.CultureInfo culture)
{
    int v = (int)value;
    int p = int.Parse((string)parameter);
    return string.Format("0x{0:X" + p.ToString() + "}", v);
}

XAML의 ConverterParameter에  지정한값은 세 번째 인자인 parameter로 전달된다.

parameter는 문자열 형식이므로 int로 파싱한다.
매개 변수가 6이기 때문에 16진수를 6자리로 표시한다.

다운로드 : BindingDemo_ConverterParameter.zip

참고 :
http://cswpf.seesaa.net/index-7.html