데이터 바인딩은 WPF 에서 중요한 개념 중 하나로 간단히 말하면 UI와 데이터를 연결해주는 다리라고 생각하면 됩니다. 데이터 바인딩을 하면 UI 속성과 데이터가 연결 되어 자동으로 동기화가 됩니다. 또한 방향도 설정할 수 있어, 데이터 값이 변경되면 UI가 갱신 되게 할 수도 있고, UI가 변경되어서 데이터가 갱신 되게 할 수도 있습니다.
만약 TextBox의 Text 속성에 Value라는 데이터 소스를 바인딩을 할 때 아래와 같이 사용합니다.
<TextBox Text="{Binding Value}" />
<TextBox Text="{Binding Path=Value}"/>
데이터 바인딩 예시
예시를 통해 알아보겠습니다. 프로젝트를 하나 생성한 뒤 MainWindow.xaml에 아래와 같이 입력해줍니다.
<Window x:Class="_05_DataBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<!--TextBox의 Text가 바인딩 됨-->
<TextBox x:Name="tbColor" Text="Yellow" Margin="5"/>
<Label Background="{Binding Text, ElementName=tbColor}" Content="This is Label" Margin="5"/>
</StackPanel>
</Window>
먼저 실행 화면을 먼저 보겠습니다.
텍스트 박스에 영어로 색상을 입력하면, 라벨의 백그라운드 색상이 변경됩니다. TextBox 요소 이름을 tbColor로 정의 한 뒤, Label의 Background 속성에 tbColor의 텍스트를 바인딩 하였기 때문입니다.
아래는 또 다른 예시입니다.
<Window x:Class="_05_DataBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<!--TextBox의 Text가 바인딩 됨-->
<TextBox x:Name="tbColor" Text="Yellow" Margin="5"/>
<Label Background="{Binding Text, ElementName=tbColor}" Content="This is Label" Margin="5"/>
<!--slider의 Value가 Binding됨-->
<Slider x:Name="slider" Minimum="0" Maximum="100" Value="50" Margin="5"/>
<ProgressBar Value="{Binding Value, ElementName=slider}" Height="30" Margin="5"/>
<TextBox Text="{Binding Value, ElementName=slider}" Margin="5"/>
</StackPanel>
</Window>
위와 같이 입력해서 실행 시키면 아래와 같이 표시됩니다.
슬라이더에 slider라는 이름을 정의 한 뒤 프로그레스바와 텍스트박스에 slider의 Value 속성을 바인딩 했습니다. 그래서 슬라이더를 변경하면 프로그레스바와 텍스트박스가 변경됩니다.
바인딩 방향
두번째 예시에서 텍스트박스에 숫자를 입력하면 슬라이더의 값도 변경하는 것을 볼 수 있습니다. 그 이유는 TextBox의 데이터 바인딩이 양방향(TwoWay)로 되어있기 때문입니다. 양방향으로 되어있다는 것은 Slider의 Value가 TextBox로 동기화되기도 하고, TextBox의 Text가 Slider의 Value로 동기화 된다는 의미입니다.
아래 표는 바인딩 방향에 대한 설명 입니다.
모드 | 방향 | 설명 |
---|---|---|
OneWay | 소스 → 타겟 | 소스에서 타겟으로만 전달됨 |
TwoWay | 소스 ↔ 타겟 | 소스와 타겟이 서로 데이터를 동기화함 |
OneTime | 소스 → 타겟 (한 번만) | 초기 한 번만 소스 데이터를 타겟에 전달, 이후 변경 반영 안 됨 |
OneWayToSource | 타겟 → 소스 | 타겟에서 소스로만 데이터가 전달됨 (소스 → 타겟 반영 없음) |
Default | 컨트롤에 따라 다름 | 대부분의 컨트롤은 OneWay, 일부는 TwoWay로 자동 설정됨 |
위 모드 중에 OneWay 텍스트박스에 설정해보겠습니다.
<!--slider의 Value가 Binding됨-->
<Slider x:Name="slider" Minimum="0" Maximum="100" Value="50" Margin="5"/>
<ProgressBar Value="{Binding Value, ElementName=slider}" Height="30" Margin="5"/>
<TextBox Text="{Binding Value, ElementName=slider, Mode=OneWay}" Margin="5"/>
이렇게 OneWay로 설정하면 소스(Slider의 Value)에서 타겟(TextBox)으로만 전달 되고, 타겟에서 소스로 전달되지는 않습니다.
다른 모드 값도 직접 입력해서 동작하는 것을 보시길 바랍니다.
UpdateSourceTrigger
데이터 바인딩에서 방향도 중요하지만 동기화 되는 시점도 중요합니다. 그 시점을 결정하는 속성이 UpdateSourceTrigger 입니다. TwoWay 모드일 때 TextBox와 Slider의 갱신을 보면 조금 다릅니다. Slider는 변경되면 TextBox에 데이터가 동기화 되는데, TextBox는 포커스를 잃었을 때 Slider에 데이터가 동기화 됩니다.
이 동기화 시점은 UpdateSourceTrigger에서 변경 가능합니다. 아래 표는 UpdateSourceTrigger에 입력하는 값 대한 설명입니다.
UpdateSourceTrigger 값 | 반영 시점 | 설명 |
---|---|---|
Default | 컨트롤에 따라 다름 | 보통 TextBox.Text는 LostFocus, 다른 컨트롤은 PropertyChanged |
PropertyChanged | 입력 값이 변할 때마다 즉시 반영 | 실시간 데이터 동기화에 적합 |
LostFocus | 포커스를 잃을 때 반영 | TextBox의 기본값 |
Explicit | 수동으로만 반영 | 코드에서 BindingExpression.UpdateSource()로 직접 호출해야 함 |
PropertyChanged는 입력 값이 변할 때마다 즉시 반영하게 해줍니다. 아래와 같이 TextBox에 UpdateSourceTrigger=PropertyChanged를 입력하면 TextBox의 값이 변할 때마다 Slider에 즉시 반영 됩니다.
<!--slider의 Value가 Binding됨-->
<Slider x:Name="slider" Minimum="0" Maximum="100" Value="50" Margin="5"/>
<ProgressBar Value="{Binding Value, ElementName=slider}" Height="30" Margin="5"/>
<TextBox Text="{Binding Value, ElementName=slider, UpdateSourceTrigger=PropertyChanged}" Margin="5"/>
github : https://github.com/3001ssw/c_sharp/tree/main/WPF/WPF_MVVM_1Week/05_DataBinding