Introduction

WPF를 이용해 MVVM패턴으로 개발할때, ViewModel에서 View에 있는 객체에 Binding을 해야 할경우, ViewModel에서 View에 있는 객체를 직접 Access해야 하므로, View와 ViewModel의 독립성이 떨어지게 됩니다. 이번시간에는 이러한 상황에서 MarkupExtension을 이용해 View에서 ViewModel의 독립성을 유지한체 ViewModel에서 View를 Binding할 수 있도록 하는 ReverseBinding을 구현 하는 방법에 대해 소개합니다.

Create DemoView(Default Data Binding)

ReverseBinding를 구현하기에 앞서 ReverseBinding을 테스트 하기 위한 상황을 만들기 위해 위와 같이 두개의 RadioButton이 있는 간단한 DemoView를 구현했습니다. 그리고 RadioButton에 ViewModel에 정의된 IsMale속성을 Binding하고, 텍스트 박스에도 IsMale 속성을 Binding합니다. 아래는 DemoView에 해당하는 소스코드입니다.


대충 눈으로 살펴봤을때는 특별하게 문제가 없는 코드 같지만, 실제로 동작을 시켜보면 동영상과 같이 DataBinding이 정상적으로 동작하지 않는것을 확인 하실 수 있습니다.
 
이유는 RadioButton의 특성상 IsChecked 속성이 변경될때 같은 Group내에 포함된 다른 RadioButton들의 IsChecked속성이 영향을 받게되는데, 이 과정에서 Binding되어있던 IsChecked속성에 다른 값이 덮여 씌워지면서  Binding이 해제되어 버리기 때문입니다.
 
이를 해결하기 위한 RadioButton에 Binding을 하지 않고, 아래와 같이 IsMale속성에 RadioButton의 IsChecked속성을 Binding하는 방법을 사용 할 수 있습니다.
하지만 위에서 언급 했듯이 ViewModel에서 View 객체를 멤버를 직접 제어하는 방법은 독립성이 떨어지기 때문에 View와 ViewModel에 종속받지 않고 위와 같은 동작을 수행하는 ReverseBinding을 직접 구현해서 사용 할 수 있습니다.

Create ReverseBinding Extension

아래는 ReverseBinding을 구현한 소스코드의 일부분으로, 요약하면 Binding객체를 파라미터로 받는 MarkupExtension을 생성하고, ProvideValueTarget을 이용해 Source Object와 Source Property를 가져온 뒤, DataContext의 Target Property에 Binding을 수행하는 과정을 나타냅니다.
위와 같이 구현된 ReverseBinding을 이용해 실제 XAML에서 사용할 때에는 아래와 같이 사용할 수 있습니다.


실행시켜보면 아래 동영상과 같이 Binding이 정상적으로 동작하는것을 확인 하실 수 있습니다.


아래는 이번시간에 사용된 전체소스코드입니다. 혹시 글을 읽으시고 이해가 안되시는 부분이나, 기타 문의사항은 댓글이나 이메일로 남겨주시면 답변드리도록 하겠습니다.

신고