데이터 바인딩 3

지금까지는 UI가 바뀔때 Binding 소스가 업데이트 되는 것을 확인 하였다.
이번에는 Binding 소스가 업데이트 되면 UI가 바뀌도록 해보자.

INotifyPropertyChanged를 이용한 바인딩 소스 업데이트

TextBox의 포커스가 바뀌면 Label 값도 같이 바뀐다.
버튼은 포커스 이동을 위해 추가 되었다.
실행 결과 화면을 먼저 보자.

<Canvas>
    <TextBox Canvas.Left="34" Canvas.Top="53" Height="22" Name="textBox1" Width="125" Text="{Binding Message}"/>
    <Button Canvas.Left="34" Canvas.Top="93" Content="Button" Height="27" Name="button1" Width="120" />
    <Label Canvas.Left="36" Canvas.Top="12" Height="28" Name="label1" Width="83" Content="{Binding Message}" />
</Canvas>

Text="{Binding Message}

TextBox의 Text에 Message를 바인딩 한다.

Content="{Binding Message}

Label의 Content에 Message를 바인딩 한다.

using System.ComponentModel;

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

         public MainWindow()
        {
            InitializeComponent();

             this.DataContext = this;
        }

        public event PropertyChangedEventHandler PropertyChanged;

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

using System.ComponentModel;

INotifyPropertyChanged를 사용하기 위해서 ComponentModel을 using 한다.

public partial class MainWindow : Window, INotifyPropertyChanged

INotifyPropertyChanged를 상속한다.

OnPropertyChanged("Message");

Message가 업데이트 되면 다른 바인딩 된 모든 컨트롤을 업데이트 하기 위해 OnProperty( )를 호출한다.

public event PropertyChangedEventHandler PropertyChanged;

INotifyPropertyChanged 인터페이를 상속하면 이벤트 PropertyChanged는 반드시 정의 되어야 한다.

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

TextBox의 입력된 문자열이 바뀌면 반인딩 된 Message 속성이 불린다.
Message 속성은 OnPropertyChanged( ) 메쏘드를 호출한다.
OnProertyChanged 메쏘드안의 PropertyChanged는 모든 컨트롤이 업데이트로 되도록 한다.

다운로드 : BindingDemo_PropertyChanged.zip

 

UpdateSourceTrigger로 즉시 업데이트

지금 까지는 포커스가 바뀌면 라벨의 값이 업데이트 되었지만 즉시 업데이트 되도록 해보자.
XAML 파일만 수정한다.

<Canvas>
    <TextBox Canvas.Left="34" Canvas.Top="53" Height="22" Name="textBox1" Width="125" Text="{Binding Message, UpdateSourceTrigger=PropertyChanged}"/>
    <Label Canvas.Left="36" Canvas.Top="12" Height="28" Name="label1" Width="83" Content="{Binding Message}" />
</Canvas>

UpdateSourceTrigger로 업데이트 시기를 조정 할 수 있다.

Text="{Binding Message, UpdateSourceTrigger=PropertyChanged}

XAML의 UpdateSourceTrigger를 PropertyChanged로 하여 즉시 업데이트 되도록 하였다.

UpdateSourceTrigger에는 다음과 같은 설정이 있다.

멤버 이름 설명
Default

기본 UpdateSourceTrigger 의 값은 바인딩 대상 속성이다.
대부분의 기본값은 종속성 속성 PropertyChanged이다.
Text 속성의 기본 값은 LostFocus이다.

Explicit

소스 코드상에서 UpdateSource 메서드 호출시 Binding 소스 업데이트

LostFocus 컨트롤 포커스가 바뀌었을 때 Binding 소스 업데이트
PropertyChanged Binding 된 컨트롤의 속성 값이 업데이트 되면 Binding 소스도 즉시 업데이트 된다.

다운로드 : BindingDemo_UpdateSourceTrigger.zip

 

다른 컨트롤의 속성 바인딩 하기

XAML에서 다른 컨트롤의 속성를 직접 바인딩 해서 업데이트 할 수도 있다.
소스 수정없이 XAML만 조작해서 적용해본다.

슬라이드바를 움직이면 텍스트 블록이 같이 업데이트 되도록 해본다.

모는 컨트롤을 삭제하고 TextBlock 한 개, Slider 한 개를 배치한다.
Slider 이름은 mySlider로 한다.

INotifyPropertyChanged 관련된 소스는 주석처리한다.

<Canvas>
    <Slider Canvas.Left="15" Canvas.Top="24" Height="25" Name="mySlider" Width="189" />
    <TextBlock Canvas.Left="23" Canvas.Top="64" Height="23" Width="70" Text= "{Binding Value, ElementName = mySlider}" />
</Canvas>

Text= "{Binding Value, ElementName = mySlider}"

다른 컨트롤의 속성을 바인딩 하는 경우 ElementName에 대상 컨트롤의 이름을 설정한다.
슬라이드 바가 움직이면 TextBlock도 같이 업데이트 된다.

어떤 소스 수정도 없이 XAML 만으로 가능하다.

다운로드 : BindingDemo_ElementName.zip

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