본문 바로가기

Development/WPF

WPF Method Binding Extension for MVVM

Introduction

WPF를 이용해 MVVM패턴으로 개발할때 데이터는 DataBinding을 사용자 입력은 Command를 사용해 View와 ViewModel을 느슨하게 연결합니다. 이것만으로도 충분히 디자인 코드와 로직 코드를 효과적으로 나눌 수 있기 때문에 많이 사용되고 있지만 Command로는 처리하기 까다롭거나 Command를 제공하지 않고 이벤트로만 제공되는 기능을 처리할 때(ex. MouseEvent, SelectionEvent 등)는 View와 ViewModel의 경계가 모호해져 완벽한 분리를 하기가 어렵습니다.

(Trigger와 Action을 이용해 일부 EventTrigger와 InvokeCommandAction을 통해 Event를 Command로 전달 할 수 있지만, 각 Event에 대해 모두 Command를 만들어 줘야 하고 파라미터에 대한 정보 또한 전달 할 수 없기에 이방법은 이번시간에서는 다루지 않습니다.)

이번시간에는 MVVM으로 개발 할 때 ViewModel에 구현되어있는 Method를 Event, Command, Property에 바인딩 할 수 있는 MethodBinding을 구현하는 방법에 대해 소개합니다.

MethodBinding

MethodBinding과 DataBinding의 가장큰 차이점은 바인딩 하는 대상이 다릅니다. DataBinding은 Source객체의 Property를 바인딩하지만 MethodBinding은 Method를 바인딩 합니다. 또 전용 Provider를 통해 Method를 전달 해 주기 때문에 Target객체의 속성이 Delegate Property가 아닌 Event, Command형태로 있다하더라도 대응이 가능합니다.

아래와 같이 ViewModel이 정의되어있다라고 했을때

MethodBinding의 적용하면 아래와 같이 사용할 수 있습니다.
그리고 ViewModel은 아래와 같이 구성되었습니다.

Create MethodBindingExtension

MethodBinding은 크게 3가지 파트로 나뉘며 각 파트별 설명은 아래와 같습니다.

  1. MethodBinding Extension : MarkupExtension으로 MethodBindingProvider의 Proxy Method를 생성
  2. MethodBindingProvider : 대상 객체의 DataContext로부터 Method Path를 추출하여 메서드를 호스팅
  3. CommandProvider : 대상 Property가 Command형식 일경우 Method를 Command로 감싸는 역할

아래는 MethodBindingExtension의 MethodBindingProvider를 생성하고 ProxyMethod를 구현하는 코드입니다.

대상 Property의 Handler Type을 추출하고 HandlerType의 Parameter들을 object[] 파라미터로 변환한 뒤 MethodProviderHandler를 호출 하는 LamdaExpression을  생성합니다. 동적으로 Handler Type에 대한 Proxy Method를 다양한 형태의 Delegate를 처리 할 수 있습니다.

아래는 이번시간에 구현한 MethodBinding의 전체 소스코드이며 기타 궁금하신 점이나 문의 사항은 메일이나 댓글로 남겨주시면 답변드리겠습니다.

WIT.WPF.MethodBindingExample.zip