간단하지만 강력한 WPF MVVM 라이브러리를 개발 중입니다.
WPF MVVM는 구조적으로 매우 큰 이점이 있지만 구현을 하기 위한 코드가 대폭 증가합니다.
그래서 코드를 줄이기 위해 Caliburn.Micro 같은 MVVM 라이브러리들을 사용하기도 하는데 일반적으로 공용 라이브러리들은 시간이 갈수록 많은 기능들이 추가되면서 비대해지는 경향이 있습니다.
그래서 개인적으로는 솔루션에 Nuget 패키지의 사용을 극도로 제한하고 있고 Log, Entity Framework과 같은 필수적인 라이브러리조차 간단하게 만들어 사용하고 있습니다.
현재 만들고 있는 MVVM 라이브러리에 현재 구현된 주요 기능은 모든 View의 컨트롤과 ViewModel의 코드가 자동 바인딩 되는 것 입니다.
xaml과 code-behind에 Command, Binding 관련 단 한 줄의 코드도 필요하지 않습니다.
- 컨트롤의 이름과 동일한 이름의 메서드가 있으면 자동 바인딩 됩니다.
예를 들어 xaml에 <Button Name="TestButton"> 컨트롤이 있고 코드에 public void TestButton() 메서드가 있으면 자동으로 버튼 클릭시 TestButton이 실행됩니다.
리소스에 동일한 이름의 KeyGesture가 있으면 자동 바인딩이 되고 컨트롤이 MenuItem일 경우 자동으로 InputKeyGesture가 설정이 됩니다. - 컨트롤+속성명과 동일한 이름의 속성이 있으면 자동 바인딩 됩니다.
코드에 public bool TestButtonIsEnabled { get; set; } 이 있으면 자동으로 TestButton의 IsEnabled 속성과 바인딩이 됩니다.
BindingMode는 속성의 종류에 따라 가장 적합한 BindingMode가 자동으로 선택됩니다. - 바인딩된 데이터의 업데이트 또한 set에서 OnPropertyChanged(속성명)을 사용하는 것보다 훨씬 간단하게 처리합니다.
- 동적으로 컨트롤을 생성하더라도 컨트롤을 생성자 안에서 생성하고 이름을 메서드 또는 속성에 맞춰 설정하면 자동 바인딩 됩니다.
MVVM 사용의 가장 큰 단점인 복잡한 바인딩을 줄였기 때문에 이벤트 방식의 코딩보다 훨씬 적은 코드로 MVVM 개발을 할 수 있습니다.
이벤트 방식은 최소한 xaml이나 코드에 이벤트를 등록해 주는 코드와 컨트롤의 속성을 직접 변경하는 코드를 작성해야 하는데 위 라이브러리는 이벤트 등록 코드를 생략하고 컨트롤의 속성 변경 또한 코드의 속성에 값을 넣는 것으로 끝이기 때문이죠.
구현 방법에 대한 힌트를 몇 가지 드리겠습니다.
- 모든 컨트롤, 메서드, 속성을 자동 바인딩하기 위해서는 정보가 필요한데 GetType().GetMethods()는 모든 메서드를 읽어서 Dictionary를 만듭니다.
- 모든 속성들은 GetType().GetProperties()를 사용합니다.
- 모든 컨트롤들은 LogicalTreeHelper를 사용합니다.
- Dictionary를 만들 때 읽은 메서드, 속성, 컨트롤들의 정보를 확인하여 유효한 것들만 추가해야 합니다.
- 모인 Dictionary 들을 루프를 돌려 적절한 바인딩을 수행합니다.
- 바인딩에 필요한 Command 속성은 ExpandoObject를 활용하여 동적으로 생성합니다.
위의 기술들을 이용해 구현하면 빠르고 간편한 자동 바인딩을 MVVM에서 사용할 수 있습니다.