11장. WPF 데이터바인딩 실습

11장. WPF 데이터바인딩 실습

참조

목적

  • WPF 데이터바인딩(DataBinding)에 대해서 학습합니다.

데이터 바인딩(Data Binding) 실습(OneWay, TwoWay, OneWayToSource, OneTime)

  • TextBox의 Text 속성과 Label의 Content 속성을 바인딩 하는 예제를 작성합니다.
  • TextBox의 값을 수정하면 Text 속성의 값을 Label의 Content 속성에 바인딩 하는 예제 입니다.
  • C# 코드에서 TextBox의 TextChanged 이벤트 핸들러를 이용하거나 또는 아래처럼 XAML 파일과 같이 데이터 바인딩을 정의할 수 있습니다.

MainWindow.xaml

<Window x:Class="WPF11_Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPF11_Test"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="300">
    <StackPanel>
        <!--Source-->
        <TextBox x:Name="txt1" Margin="24"/>

        <!--Target-->
        <!--ElementName=txt1 대신 Source={x:Reference txt1} 가능-->
        <Label HorizontalAlignment="Center"
               BorderBrush="Black"
               BorderThickness="2"
               Content="{Binding ElementName=txt1, Path=Text}"/>
    </StackPanel>
</Window>

1

  • 바인딩 자체는 언제나 타겟에 설정합니다.
  • Binding 키워드는 마크업 확장으로 Content 속성의 중괄호안에 Binding 키워드가 있다.
  • Binding의 속성 중 ElementName은 소스 객체를 지정하는데, TextBox의 Name속성에 정의된 이름이 사용되었고, Path 속성에는 소스 객체의 속성이 와야 하는데, TextBox의 Text 속성이 설정되었습니다.
  • 바인딩 정의가 있는 컨트롤은 기본적으로 항상 타겟 입니다.
  • 바인딩 타겟은 DependencyObject로부터 상속되며 바인딩이 설정되는 속성은 반드시 의존 프로퍼티의 지원을 받아야 한다.
  • 바인딩 소스는 반드시 의존 속성일 필요는 없습니다.

XAML이 아닌 C# 코드로 데이터 바인딩 하는 방법

  • XAML이 아닌 C# 코드로도 데이터 바인딩을 할 수 있습니다.

MainWindow.xaml

<Window x:Class="WPF11_Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPF11_Test"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="300">
    <StackPanel>
        <!--Source-->
        <TextBox x:Name="txt1" Margin="24"/>

        <!--Target-->
        <!--ElementName=txt1 대신 Source={x:Reference txt1} 가능-->
        <Label HorizontalAlignment="Center"
               BorderBrush="Black"
               BorderThickness="2"
               Name="label"/>
    </StackPanel>
</Window>

MainWindow.xaml.cs

using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

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

            Binding bind = new Binding();
            bind.Source = txt1;
            bind.Path = new PropertyPath(TextBox.TextProperty);

            //SetBinding의 첫 번째 인자는 DependencyProperty 타입이 되어야 한다.
            //그러므로 타겟의 속성은 의존속성의 지원을 받는 속성이 되어야 한다.
            label.SetBinding(Label.ContentProperty, bind);
        }
    }
}

바인딩 모드 종류와 실습

  • 소스와 타겟의 의미는 소스 속성의 변화를 타겟의 속성에 반영되도록 하는 의미를 담고 있습니다.
  • 바인딩 모드는 4가지 모드 입니다.
  • Binding의 Mode 속성의 기본값은 Default인데 TextBox처럼 사용사가 편집 가능한 컨트롤 속성의 기본값은 양방향 바인딩으로 설정되지만 대부분의 경우 기본값은 단방향 바인딩으로 설정됩니다.
  • TwoWay 로 설정할 수도 있는데 Label의 Content 프로퍼티의 변화도 TextBox의 Text 프로퍼티에 반영됩니다.
  • OneTime 모드도 있는데 타겟이 소스로부터 초기화 되지만 소스의 변화가 계속 반영되지 않고 초기 한 번만 반영됩니다.
  • OneWayToSource 모드는 소스, 타겟의 의미가 반대가 되도록 타겟이 소스를 갱신하는 모양이다. 본 예제의 경우 Label은 TextBox에 넘겨줄 데이터가 없기에 Label은 비어있고 TextBox의 Text 속성을 변경해도 반응이 없는 형태가 됩니다.
<Window x:Class="WPF11_Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPF11_Test"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="300">
    <StackPanel>
        <!--Source-->
        <TextBox x:Name="txt1" Margin="24"/>

        <!--Target-->
        <!--ElementName=txt1 대신 Source={x:Reference txt1} 가능-->
        <Label HorizontalAlignment="Center"
               BorderBrush="Black"
               BorderThickness="2"
               Content="{Binding ElementName=txt1, Path=Text, Mode=OneWayToSource}"/>
    </StackPanel>
</Window>
  • Label이 소스가 되고 TextBox가 타겟이 되었는데 Label의 Content를 "대한민국" 으로 설정했으므로 최초 TextBox의 Text 속성에 반영이 되었습니다.
  • TextBox의 값을 바꾸면 라벨 값이 갱신되는 TwoWay 바인딩이 기본적으로 설정되어 있는데, 만약 여기에서 Mode를 OneWay로 설정하면 TextBox의 값을 수정해도 라벨의 Content 프로퍼티는 갱신되지 않습니다.
  • Mode를 OneWayToSource로 하면 동작합니다. 소스와 타겟을 바꾸어서 동작하기에 동작을 하는데, 현재 타겟인 TextBox를 수정하면 소스인 라벨에 반영이 되는 것입니다. TextBox의 Text 속성에 대해 초기값은 별도로 지정하지 않았으므로 빈 값이 Label 에 반영되고 이후 TextBox의 Text속성을 수정하면 Label의 Content 속성이 바뀌게 됩니다.
<Window x:Class="WPF11_Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPF11_Test"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="300">
    <StackPanel>
        <!--Binding Target-->
        <!--UpdateSourceTrigger 는 타겟이 소스를 갱신하는 타이밍을 지정-->
        <!--TextBox인 경우 LostFocus가 기본이므로 값이 바뀔때마다 갱신하기 위해 PropertyChanged 발행-->
        <TextBox Margin="24"
                 Text="{Binding ElementName=label, Path=Content,
            UpdateSourceTrigger=PropertyChanged}"/>

        <!--Binding Source-->
        <Label Name="label" Content="대한민국"
               HorizontalAlignment="Center"
               BorderBrush="Black"
               BorderThickness="2"/>
    </StackPanel>
</Window>
728x90

이 글을 공유하기

댓글

Designed by JB FACTORY