Binding이란, WPF에서 XMAL 코드로 구현된 View와 DataContext로 사용될 ViewModel이 데이터를 상호 의존하지 않고 주고 받을 수 있도록 해주는 기능이다. 각 계층간의 분리가 핵심인 MVVM 디자인 패턴을 적용하기 위해 필수적인 요소라고 할 수 있다.
MVVM에서의 Binding에 대한 자세한 설명은 아래 글에서 이미 다루었으므로 이번 글에서는 Binding의 간단한 사용법에 대해서만 정리하고자 한다.
[.NET Framework/WPF] - [WPF] MVVM 디자인 패턴 (2)
1. Binding 해보기
Binding은 보통 View에 속한 컨트롤의 속성과 ViewModel에 속한 속성을 연결하기 위해 사용되며, XAML 코드 내에서 이뤄진다. Binding이 이뤄졌을 때, View에 속한 컨트롤의 속성을 Binding 대상, ViewModel에 속한 속성을 Binding 소스라고 칭한다.
런타임에서 UI는 ViewModel의 PropertyChanged 이벤트에 콜백 메서드를 등록하게 되고, PropertyChanged 이벤트가 발생하게 되면 Binding된 속성의 이름을 ViewModel에서 검색하여 값을 가져와 컨트롤의 속성값으로 지정하게 되는 것이다.
<TextBlock Text="{Binding MyText}" />
Binding을 하기 위해서는 위와 같이 Binding 대상의 속성에 {} 태그 확장을 사용하여 속성 이름을 지정한다.
위 코드는 MyText라는 속성값을 가져와 TextBlock의 Text 속성에 지정하라는 의미이다.
MyText 속성이 실제로 DataContext에 존재하는지의 여부는 중요하지 않다. Binding된 속성이 존재하지 않더라도 프로그램이 컴파일되거나 실행되는데는 지장이 없으며, TextBlock의 Text 속성은 코드 비하인드 등에서 직접 변경하지 않는 한 그대로 유지될 뿐이다.
2. Binding의 방향 (Mode)
Binding은 Mode라는 추가 속성을 사용하여 데이터 흐름의 방향을 지정할 수 있다.
아래 표를 참고하자.
속성값 (BindingMode) | 동작 방식 |
Default | 기본값이다. Binding될 속성에 따라 다른 데이터 흐름으로 동작한다. 일반적으로 사용자가 상호작용을 통해 편집 가능한 속성들은 TwoWay 방식으로 동작하고, 이를 제외한 대부분의 속성들은 OneWay 방식으로 동작한다. |
OneTime | 프로그램이 시작되는 시점 또는 View의 DataContext로 지정된 개체가 변경되는 시점에서 1회에 한하여 바인딩 대상의 값을 바인딩 소스의 값으로 업데이트한다. (ViewModel → View) |
OneWay | 바인딩 소스의 값이 변경되면 바인딩 대상의 값이 업데이트된다. (ViewModel → View) |
OneWayToSource | 바인딩 대상의 값이 변경되면 바인딩 소스의 값을 업데이트한다. (View → ViewModel) |
TwoWay | 바인딩 소스 또는 바인딩 대상의 값이 변경되면 다른 쪽의 값도 업데이트한다. (View ↔ ViewModel) |
Mode를 따로 지정하지 않은 경우 Default로 동작하며, 사용자가 상호작용으로 값을 편집할 수 있는 속성(예를 들어 TextBox.Text나 CheckBox.Checked 처럼)의 경우 TwoWay 방식으로, 그렇지 않은 경우 OneWay 방식으로 동작한다고 보면 된다.
Mode는 아래와 같이 지정한다.
<TextBox Text="{Binding UserID, Mode=OneWayToSource}" />
위 코드는 사용자의 ID를 입력받기 위한 텍스트 박스에 사용자로부터 입력되는 값을 ViewModel로 전달하기 위해, 그리고 ViewModel에서 값을 가져올 필요는 없으므로 Mode를 OneWayToSource로 지정하였다.
3. Binding 했는데 값이 바뀌지 않아요!
Binding을 한다고 하더라도 UI 스레드는 대상 또는 속성의 값을 계속 모니터링하고 있지는 않다. 값이 언제 어느 시점에 바뀔지 예측할 수 없기 때문에 값을 계속 비교하면서 모니터링 하는 것은 작업량을 매우 늘리기 때문이다.
Binding 대상과 Binding 소스가 값을 주고 받도록 하는 트리거 역할을 하는 것이 INotifyPropertyChanged의 PropertyChanged 이벤트이다. Binding 소스 측에서는 값이 변했을 때 PropertyChanged 이벤트를 발생시켜서 Binding 대상이 업데이트되도록 알려줄 필요가 있다. 이것이 오직 속성만이 Binding의 대상과 소스가 될 수 있는 이유이기도 하다.
우리에게 보이지는 않지만 WPF 애플리케이션의 뒷단에서는 PropertyChangedEventManager가 Binding된 속성을 소유하는 클래스들의 PropertyChanged 이벤트에 콜백 메서드를 등록하여 이벤트가 발생했을 때 DataBindEngine이 이를 처리할 수 있게 전달하고 있다.
실제로 디버그 모드로 실행 후 PropertyChanged 이벤트를 조사해보면 우리가 등록한 적 없는 메서드가 등록되어 있는 것을 확인할 수 있는데, 이것이 PropertyChangedEventManager의 OnPropertyChanged 메서드이다.
요약하면 데이터 바인딩이 이루어지도록 하기 위해 여러분은,
- 바인딩 소스를 소유하는 ViewModel은 INotifyPropertyChanged 인터페이스를 구현해야 한다.
- 바인딩 소스가 바뀌었을 때 PropertyChanged 이벤트를 발생시켜야 한다.
이 부분은 ViewModelBase에 대해 설명한 아래 글을 참고하자.
[.NET Framework/WPF] - [WPF] MVVM 디자인 패턴 (3) - ViewModelBase
'.NET > WPF' 카테고리의 다른 글
[WPF] DependencyProperty에 대해서 - RelativeSource 사용하여 Binding하기 (0) | 2023.05.10 |
---|---|
[WPF] XAML 코드 상에서 DataContext 지정하기 (0) | 2023.01.03 |
[WPF] DependencyProperty에 대해서 (1) | 2022.11.24 |
[WPF] MVVM 디자인 패턴 (3) - ViewModelBase (0) | 2022.11.18 |
[WPF] MVVM 디자인 패턴 (2) (0) | 2022.11.13 |