WPF.. MVVM 패턴에 빠르게 적응 할 수 있는방법이 있을까요

안녕하세요 선배님들 저는 개발에대해 심도깊게 배우지 못했고 거의 필요에 의한 독학 수준입니다.
전산팀 직원이면서 닷넷 프레임워크3.5 윈폼 프로그램들을 유지 보수 하고있습니다.
(서버 클라이언트 프로그램)
타부서 요청이나 필요에 의해 간단한 유틸리티정도는 신규 개발도 하고있구요.

내년에 순차적으로 가벼운프로그램들부터 MVVM 패턴의 WPF로 프로그램들을 바꾸기 시작하게 되었는데요 (최근 DevExpress 구매) 데모 프로그램 소스를 봐도…
구글링해서 보아도… 패턴이나… 데이터바인딩등 전반적으로 이해가 잘 되지 않습니다…
남은시간이 얼마 되지 않다보니 막막하네요… ^^;;

어떤식으로 접근을 하는게 빠르고 효율적으로 학습할 수 있을지 간단한 조언이라도 좋으니 부탁드릴수 있을까요?

1개의 좋아요

고대 그리스 수학자, '유클리드’가 이렇게 말했습니다.

“幾何學에는 王道가 없다”.

저는 C#, WPF, MVVM에 익숙해지는 것도 기막힌 지름길이 따로 없다고 생각합니다. 예전 프로그래밍 언어인 COBOL은 1년 경력이나 10년 경력이나 차이가 없었습니다. 그러나 프로그래밍 언어가 객체지향으로 바뀌고, 또 언어 자체가 나날이 진보하니 ‘꾸준한’ 학습이 아니면 도태된다고 생각합니다.

저도 C#, WPF, MVVM 에 ‘조금’ 익숙해지는 데 2년 정도 걸린 듯 합니다.

2개의 좋아요

Click Event에 비즈니스 로직 안넣는 것부터 해보면 좋을 것 같네요.

3개의 좋아요

간단한 프로그램부터 MVVM으로 만들어 보시는 걸 추천 드립니다.

제 생각에는 어떤 패턴이던지 각 레이어의 역할에 맞는 일을 하도록 만드는 것이 중점인 것 같습니다.

간단한걸 만들어보시면서 이건 뷰/뷰모델/모델의 역할에 맞는지 고민을 많이해보시는게 좋을 것 같습니다.

2개의 좋아요

조언 감사합니다… 왕도가 없단건 잘 알고있지만… 월급받으먀 일하는 입장에 갑자기 닥치니 참 막막해서 올여봤습니다 ^^;

1개의 좋아요

조언 감사합니다 !

일단 차근차근 제 개인적으로 사용하던 프로그램부터 wpf로 컨버팅 해보고있는데 쉽지 않네요 ^^ 조안 감사합니다!

1개의 좋아요

https://jamesnet.dev/store
이책 권합니다. 제가 지금 이책 보고 정말 배우고있습니다.

이만큼 잘만든 WPF 교재는 없는것 같습니다.

8개의 좋아요

저도 입문한지 얼마 안되었지만 저같은 경우에는 MVVM Community Toolkit 공식 문서 읽어보고 인터넷 강의 조금씩 보고 ChatGPT 이용해서 실제로 구현해보면서 공부했습니다.

1개의 좋아요

WPF MVVM 일주일만에 배우기 딱… 추천드립니다.

전통적인 GUI 애플리케이션 개발에서는 아래와 같은 관념 모델을 주로 사용하셨을 겁니다.

버튼 객체 → 버튼 클릭 이벤트 → 핸들러 연결 → 이벤트 핸들러에서 컨트롤 속성 직접 수정

매우 직접적이고 직관적인 구현 방식이긴 하지만, 이 경우 화면의 요소가 어떻게 변경되는가에 따라 수정해야 할 코드의 양이 크게 늘어난다는 문제가 있습니다.

그래서 약간은 간접적이고 돌아가는 것 같은 느낌이 들 수 있지만, 이벤트 핸들러나 컨트롤 속성을 코드에서 직접 수정하지 않고, 별도의 바인딩 엔진이 대신 처리하도록 연결해주는 것이 MVVM의 기본 원리라고 보시면 어렵지 않습니다. (다만, 패턴이 생소하기 때문에 오는 러닝 커브는 분명 존재합니다. 그리고 뷰 모델을 따로 정의해주어야 한다는 점이 초반의 구현 상의 일거리를 늘어나게 만드는 느낌도 받으실 수 있고, 무엇보다도 화면의 논리적 구조를 기획 단계에서 정의해야 하는 행위가 부담스럽게 느껴질 수도 있습니다.)

예를 들어 버튼 클릭 이벤트는 버튼의 “명령(Command)” 속성으로 정의할 수 있고, 이렇게 드러난 명령 속성에 이벤트 핸들러 대신 명령 객체를 연결하게 됩니다.

이때 명령 속성에 연결되는 객체는 자신이 어떤 GUI 플랫폼—Windows Forms인지, WPF인지, Blazor인지, MAUI인지—에 연결될지 알 필요도 없고, 몰라도 잘 작동할 수 있어야 합니다.

그렇다면 명령 속성과 연결될 데이터는 어떻게 처리할 수 있을까요? 이 부분에서 뷰 모델(ViewModel)의 역할이 시작됩니다. 뷰 모델은 속성이 바뀔 때 MVVM 엔진에게 이를 알려줄 수 있어야 하고, 이를 위해 INotifyPropertyChanged 인터페이스를 뷰 모델에서 구현하게 됩니다.

public class DemoCustomer : INotifyPropertyChanged  
    {  
        // These fields hold the values for the public properties.  
        private Guid idValue = Guid.NewGuid();  
        private string customerNameValue = String.Empty;  
        private string phoneNumberValue = String.Empty;  

        public event PropertyChangedEventHandler PropertyChanged;  

        // This method is called by the Set accessor of each property.  
        // The CallerMemberName attribute that is applied to the optional propertyName  
        // parameter causes the property name of the caller to be substituted as an argument.  
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")  
        {  
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }  

        // The constructor is private to enforce the factory pattern.  
        private DemoCustomer()  
        {  
            customerNameValue = "Customer";  
            phoneNumberValue = "(312)555-0100";  
        }  

        // This is the public factory method.  
        public static DemoCustomer CreateNewCustomer()  
        {  
            return new DemoCustomer();  
        }  

        // This property represents an ID, suitable  
        // for use as a primary key in a database.  
        public Guid ID  
        {  
            get  
            {  
                return this.idValue;  
            }  
        }  

        public string CustomerName  
        {  
            get  
            {  
                return this.customerNameValue;  
            }  

            set  
            {  
                if (value != this.customerNameValue)  
                {  
                    this.customerNameValue = value;  
                    NotifyPropertyChanged();  
                }  
            }  
        }  

        public string PhoneNumber  
        {  
            get  
            {  
                return this.phoneNumberValue;  
            }  

            set  
            {  
                if (value != this.phoneNumberValue)  
                {  
                    this.phoneNumberValue = value;  
                    NotifyPropertyChanged();  
                }  
            }  
        }  
    }  

예를 들어 위와 같은 코드가 있다고 했을 때, 값이 동일한지 아닌지 비교한 다음, NotifyPropertyChanged 메서드를 호출해서 어떤 프로퍼티가 바뀌었는지 이벤트를 발행하는 식입니다. MVVM 엔진은 PropertyChanged 이벤트 핸들러를 구독하고 있는 상태이므로 나머지는 이전에 선언적으로 연결해둔 속성 연결 관계에 따라서 알아서 속성을 업데이트할 것입니다. (NotifyPropertyChanged 메서드에 인자를 지정하지 않아도 되는 이유는 C# 언어 명세를 보시면 되겠습니다.

이렇게 하면 MVVM 엔진이 특정 속성의 변경을 감지하고, GUI도 연동해서 함께 업데이트되도록 동작하게 됩니다. 명령 객체는 GUI를 직접 제어하는 대신, 뷰 모델을 통해 필요한 동작을 간접적으로 구현하게 됩니다.

물론 이런 구현 방식이 항상 잘 작동하는 건 아닙니다. 버튼처럼 명확하고 대표적인 이벤트 속성이 있다면 통하지만, 그렇지 않은 경우 여전히 GUI에 직접 연결되는 제어 코드가 필요할 수 있습니다. 다만 핵심 비즈니스 로직과 데이터 모델을 GUI 코드에서 명확히 분리하여, 화면 구성이 어떻게 바뀌든, 어떤 GUI 프레임워크를 사용하든 관계없이 기술 스위칭이 가능하도록 만드는 것이 MVVM 구현을 택하는 가장 큰 이유이자 핵심이라고 보시면 좋겠습니다.

ps. 커맨드 패턴으로 애플리케이션의 기능들을 모두 분리시켜두었다면, MS Office의 사례처럼 프로그램 내 여러 편집 기능들을 파이썬이나 자바스크립트 등 애플리케이션 외부에서 호출할 수 있도록 내보내는 것도 가능하고, 더 나아가서는 생성형 AI와 MCP를 통합시킬 때 필요한 "애플리케이션 기능 명세"를 프롬프트에 만들어 넣고 AI가 만들어내는 출력을 따라가도록 만들 때에도 편리합니다. :smiley: