프로그래밍

WPF로 툴 만들기. MVVM은 부록! #2

zinzza 2012. 12. 9. 14:56


Apparelbase.MVVMBase.dll


안녕하세요 zinzza, 연두父, 이경배입니다.

2회입니다. 이번엔 지난번에 이어 MVVM의 장점을 이해하기 위해 또 한번 삽질의 시간을 갖고자 합니다.

하지만 이번걸 이해해야 다음 진행이 가능할거 같습니다.


C&P 한거지만... 다시한번 대상설명을 드리자면^^;;;


이 글의 대상은 엄청 간단한 C#책을 살짝쿵 읽어본 기획자, 대학, 학원등에서 C#프로그램을 좀 배운 수준의 사람들을 대상으로 적었습니다.


일단... 프로그래머 분들께서는 이 글의 오류를 찾아 저에게 제출해주시고, 그럴 목적이 아니시라면 읽지 말고 나가주세요.(부끄로아요ㅜㅜ)


아... MVVM의 장점 하나 설명하려고 별별 삽질을 다 해봅니다.
그럼 지난번에 만든걸 MVVM패턴으로 만들어보겠습니다.




먼저 새 프로젝트를 만들어봅시다.
뭐... 다 아는걸 괜히...^^;




그 다음엔 제가 첨부해 놓은 Apparelbase.MVVMBase.dll을 참조에 추가합니다.


Apparelbase.MVVMBase.dll


* 방법은 솔루션 탐색기의 참조에서 오른쪽버튼-> 참조추가-> 찾아보기 에서 찾아 추가해주시면 됩니다.

MVVM패턴을 하기 위해서는 몇가지 특정 자료형을 사용해야 하는데 그 사용을 좀 편리하게 해주는 겁니다.  저희 회사에서 사용하는 것들 중 필요한것만 살짝 뺐습니다. 그래도 괜히 우리 팀 이름을 붙여 봤습니다^^;


그리고 MainWindow를 꾸며봅시다!




역시 껍대기는 간단하게 만들 수 있으니 스킵합니다.

자~ 그 다음엔 ViewModel을 추가 해야 합니다.
뷰는? MainWindow.xaml 이 뷰 입니다^^;
모델은? 이건 좀 나중에^^;

솔루션 탐색기의 프로젝트 이름에서 오른쪽버튼 -> 추가-> 클래스 

클래스 이름은 알아보기 쉽게 MainViewModel.cs 로 가죠. 

 MainViewModel.cs를 열어서 위의 빨간부분을 입력합니다.


using Apparelbase.MVVMBase; 는 아까 추가한 dll을 이 파일에서 사용하겠다는 뜻입니다.
public은... 여기저기서 쓸려고 걍 넣은겁니다. 일단 보안은 신경 안쓰니까 편하게^^;
:ObservableObject 는 뷰모델의 기본이 되는 프로퍼티들이 정의되어있습니다.(이게 dll안에 들어있던놈입니다.) 당장 몰라도 되니 그냥 넘어가죠^^;

자~ 이제 뷰모델을 만들었으니 이 안에 데이터를 제어하는 코드들을 넣어야 합니다.
아까 만든 Winform 보다 조금 복잡한 코드입니다.
음... 우선 TestNumber 변수를 하나 선언할까요?



헉!  이게 뭔가요?


이건 변수가 아니고 프로퍼티라고 하는겁니다.  더 자세히 말씀드리면 의존프로퍼티(Defendency Property) 라고 하는거죠. 복잡한가요? 차근차근 보면 뭐^^;;




다시 한번 MVVM에 대한 그림을 보시면 Properties라는 부분이 있을껍니다.
바로 그 Property중에 하나를 선언한겁니다^^;

MVVM에서는 Property가 변하면 View에 자동으로 반영됩니다. 이거 꽤 편해요!
이번화에서는 Properties와 ICommands 를 사용할껍니다.

아! 프로퍼티에 대해서 알고 계시면 3-2의 빨간 글씨만 보시고 넘어가셔도 무방합니다.

1. 먼저 노란 #region은 신경 안쓰셔도 됩니다. 그냥 여기서부터 여기까지 TestNumber에 대한 내용이다~ 라는거고 프로그램에는 아무 역할도 안하는놈입니다.
2. 소문자로 시작하는(습관입니다)testNumber 변수는 실제 값을 저장하는 변수입니다.
3. public 으로 선언되고 대문자로 시작하는 TestNumber 가 바로 의존프로퍼티인데요
사실 이 MainViewModel을 외부에서 접근할때는 testNumber로 접근하는게 아니고 TestNumber를 통해 값을 설정하고 조회합니다.
TestNumber에는 testNumber를 설정, 조회하는 방법을 정의하는거죠.
그래서! get과 set 을 갖고 있습니다.
3-1 get은 간단하니 먼저 설명합니다.
그냥 return this.testNumber; testNumber의 값을 바로 읽는겁니다.(왜 이런 삽질을...ㅎㅎ 천천히 아셔도 됩니다. )
3-2 set 역시 this.testNumber = value; 로 TestNumber에 설정되는 값을 바로 testNumber에 지정합니다.
하지만 코드가 2줄 더 있는데요, if를 통해 같은 값인 경우 다시 지정하지 않게 하는 코드 한줄,
그리고 this.RaisePropertyChanged(“TestNumber”); 를 잘 기억해 두시기 바랍니다.
“나 변했어요~~~” 하고 프로그램한테 알려주는 메소드입니다.

음... 위 내용이 복잡하시면
변수를 선언할때 위 형태를 유지해 주시고 testNumber, TestNumber, int  이 3가지만 필요에 맞게 변형해서 사용하시면 됩니다.(저도 처음엔 그렇게 했어요)

자 이제 이걸 컨트롤 하는 ICommands를 만들어봅시다.
아! ICommand를 추가하기 전에 MainViewModel 위쪽에 using System.Windows.Input;  을 추가 해 줘야 합니다. ICommand가 여기 있거든요.
이제 추가해줍시다!


으악!!


복잡하지만 정 귀찮으시면 이번 역시 plus와 Plus 만 이름에 맞춰 바꿔쓰시면 됩니다.

물론 설명도 해야겠죠 ㅜㅜ
1. 먼저 소문자로 시작하는(역시나 습관) plusCommand 를 하나 선언하고요,
2. 대문자로 시작하는 PlusCommand를 하나 선언합니다.
get 구현하되 형식을 유지하고 그냥 plus와 Plus 부분만 수정한다고 기억하세요. 자세한 설명은 생략합니다.(너무 길어져요 ㅜㅜ)
3. CanPlus() 는 이 ICommand가 실행 가능한 상황인지 아닌지를 판단하는 메소드 입니다. 뒤에 다시 설명할꺼고요, 지금은 무조건 true를 반환하게 되어있습니다.
4. Plus() 메소드에 진짜 필요한 코드가 들어가는겁니다. 아... 이 간단한거 한줄 넣으려고 이게 뭔 짓입니까 ㅜㅜ?

마찬가지로 마이너스 커맨드도 만들어야겠죠?




뭐... plus, Plus 를 minus, Minus로 바꾼거 와 ++가 --로 바뀐거 말고는 달라진게 없군요.
암튼 이제 ViewModel을 다 만들었습니다! 실행!!!!!!!!!!! F5!!!!!!!!!!!!!!!





















.

.

.




.

.

.

.

.

.

.




































.

.

.

.

.

.

.

.

.

.

.

.

.

.














허허... 안되네....



왜 안될까요? 그건 View랑 ViewModel을 연결해주지 않았기 때문입니다.


솔루션 탐색기에서 MainWindow.xaml.cs를 선택해 줍니다.




그리고 연결하는 코드를 넣어주죠.



한줄만 넣어주시면 됩니다.  이 뷰의 뷰모델은 MainViewModel이다~ 라는 뜻이죠.

다시 MainWindow.xaml 파일을 열어서 마치 html코드 처럼 생긴 xaml코드를 봅니다.



저는 보기 편하게 하려고 Enter를 좀 쳐놔서 모양이 다를껍니다.
아마 한줄에 죽~ 나오실꺼에요.
순서대로 갑니다~
1. 먼저 Label의 Content를 “{Binding TestNumber}” 라고 수정해줍니다. - ViewModel의 TestNumber 프로퍼티를 연결한겁니다.
2. + Button에 Command="{Binding PlusCommand}" 를 추가 해 줍니다. - ViewModel의 PlusCommand ICommand를 연결한겁니다.
3. - Button에 Command="{Binding MinusCommand}" 를 추가 해 줍니다. - ViewModel의 MinusCommand ICommand를 연결한겁니다.




이렇게요^^;

아~~~~ 정말 수고하셨습니다~~~~ 이제 진짜로 F5!
실행을 확인합니다.
정말... Winform에서 간단하던 걸 왜 이 고생을 한 건지 이해가 안됩니다.


아~이해안되~~

자... 이제 거의 다 왔습니다.

앞에Winform에서 했던 3번의 수정을 더 하면 끝인거죠-_-??????????



또....-_-?



ㅎㅎㅎ 그레도 MVVM은 수정이 좀 쉬우니까요- 그래서 쓰는 거라니깐요^^;
자... 처음이 뭐였죠?
Label을 TextBox 로 변경?

해보죠 뭐.



MainWindow.xaml 파일에서 Label 을 TextBox로 수정하고 Content를 Text로 수정해주세요.(TextBox에는 Content라는 속성이 없고, Text라는 프로퍼티가 있거든요)
끗!

그 다음은 뭐였죠?
아... 0미만으로 내려가지 않기, 10초과해서 올라가지 않기였죠?
그럼 이번엔 MainViewModel의 TestNumber 프로퍼티를 보시죠.  
값을 지정하는거니까 set 부분을 수정해줘야 합니다.
if (this.testNumber != value) 부분을
if (this.testNumber != value && value >= 0 && value <= 10) 으로 수정해주세요.



0보다 작거나 10보다 큰 값은 아예 testNumber에 지정되지 않게 됩니다.
끗!

자~ 그 다음!
아! 버튼 비활성화였죠?
0일때10일때...
이번엔 PlusCommand와 MinusCommand에서 CanPlus, CanMinus 메소드를 수정해야 할 시점입니다.
CanPlus메소드에서
if (true) 를 if (this.TestNumber<10) 으로 고쳐주세요.



CanMinus메소드에서
if (true) 를 if (this.TestNumber>0) 으로 고쳐주세요.




각 커맨드가 조건에 의해서 실행되고 안되고를 지정해주는건데요, 이렇게만 해주면 버튼이 조건에 의해 자동으로 활성화, 비활성화됩니다.(오옷!)

끗!

자~~~~~ 마지막! 이름 변경!
각 컨트롤들의 Name 속성을 바꿔주세요.
코드는 바꾸실 필요 없습니다^^;(이름으로 연결된게 아니라 값 자체가 연결(Binding 된거)니까요)
끗!

아... 만들때는 좀 힘들었지만(사실 설명이 힘들고 익숙하지 않은거죠, 이텔릭체로 써놓은 것처럼 그냥 규칙대로 쓰고,  크게 어렵지도 않아요. 타이핑이 많을 뿐.)





아무튼..저는 힘들었어요.

이렇게 MVVM 패턴은 유지보수, UI수정등을 쉽게 할 수 있다는 장점을 갖고 있느 패턴입니다.
자... 아무튼 일단 MVVM과 WPF와 C#과 XML을 이용해서 우리 놀개영의 공식 동내북 달땡님이 원하는 툴을 함 만들어 보겠습니다!
고고고!



반응형