WPF의 MVVM 모델에선
View에서 UIElement를 만들고 ViewModel의 Property들과 Binding을 한다.
특정 행동을 취하고 싶을 땐 Command 객체를 ViewModel에서 생성하고,
이 Command를 View에 바인딩시킬 수 있다.
ViewModel에서 View에게 어떤 행동을 시키고자 할 때
나는 Action 객체를 ViewModel에서 만들고
View의 특정 행동과 이 Action 객체를 바인딩시켜준다.
(ViewModel에서 Action을 통해 View를 건드리는 게 옳은 방법인지 모르겠으나,
초보 개발자인 나는 일단 이런 식으로 구현한다..)
보통의 경우 위와 같이 Binding을 통해 View-ViewModel 간의 데이터 통신을 해결하였다.
오늘 업무 중 위와 같은 방식으로 해결이 잘 안되는 이슈가 있었다.
사용자가 View의 Textbox에서 Text를 입력하고 엔터를 클릭했을 때
특정 버튼을 클릭한 것과 동일한 효과를 내고 싶었는데, 이게 생각보다 쉽지 않았다.
좀 더 정확히 말하자면, 특정 버튼에 바인딩된 Command를 실행시키고 싶었다.
여기선 ApplyCommand라고 하자.
처음엔 Textbox에 KeyBinding을 넣어보았다.
<TextBox>
<TextBox.InpuBindings>
<KeyBinding Command="{Binding ApplyCommand}" Key="Enter"/>
<KeyBinding Command="{Binding ApplyCommand}" Key="Return"/>
</TextBox.InpuBindings>
</TextBox>
이런 식으로.
Command는 잘 수행되었다.
하지만 문제가 있었으니, 그건 바로 Textbox의 Text가 ViewModel에 반영이 안된다는 것이었다.
ApplyCommand는 Textbox의 Text 를 이용하기 때문에
사용자가 입력한 최신 값을 사용해야 했다.
하지만 ViewModel의 Text는 예전 값 그대로였다.
TextBox는 Focus가 다른 UIElement로 옮겨가야 PropertyChange event를 발생시키는 것 같다.
무튼...
그래서 View의 Code Behind 에서 ViewModel의 Text를 TextBox의 Text로 바꾼다음 Click 이벤트를 발생시키기로 하였다.
this.myButton.RaiseEvent(new RoutedEvnetArgs(ButtonBase.ClickEvent));
이런 식으로.
ViewModel의 Text 값은 최신 값으로 잘 바뀌었고 Click Event도 잘 수행되었다.
하지만 또 문제가 있었으니, Click 이벤트만 발생하고 Command가 호출되질 않았던 것이다.
내가 원하는 건 버튼에 할당된 Command를 수행하는 것이었기에 이 방법도 포기했다.
마지막으로 View의 Code Behind 에서 RaiseEvent() 대신 Command.Execute() 를 수행하기로 했다.
this.myButton.Command.Execute(this.myButton.CommandParameter);
이런 식으로.
드디어..!!
수행되었다. Command가.
PS ) View의 Code Behind를 사용하는 건 안좋은 습관이라고 하던데, 이럴 땐 Code Behind 없이 구현할 다른 방법이 있을까? 좀 더 나아가서 View가 동적으로 여러 동작을 하게 되면 Code Behind의 사용 없이 동적인 모든 장면들을 구현할 수 있을까?
'Development Experience > C#' 카테고리의 다른 글
C# 개발 팁 (0) | 2020.03.17 |
---|---|
c# global :: namespace (0) | 2020.03.12 |
Telerik RadTabbedView 에서 첫 Tab화면이 안나올 때 (0) | 2020.02.06 |
C# data binding 시 TreeView 에서 depth가 2 이상일 때.. (ItemsSource를 사용하려면 항목 컬렉션이 비어 있어야 합니다 Error 대처법) (0) | 2020.01.02 |
Telerik Winform에서 border의 색깔이 도저히 안 없어질때.. (0) | 2019.11.18 |