본문 바로가기

[C# WPF] MVVM 간단하게 시작하기 - 1 (데이터바인딩, 연동)

재과장 2021. 7. 19.
반응형

MVVM, Model - View - ViewModel

WPF에서 사용할 수 있는 디자인패턴입니다.

이번 글과 앞으로 이어지는 글에서 MVVM을 쉽고 간단하게 사용할 수 있도록 공부하며 배운 내용을 정리하겠습니다.

MVVM 구성도

View : 사용자가 보는 화면(UI)을 구성합니다. XAML로 구성되어 있으며 디자이너가 다룰 영역입니다.

 

ViewModel : View, UI의 실제 동작에 관련된 부분을 작성합니다. 버튼을 클릭하는 등의 여러 작업들을 이 부분에서 구성합니다.

 

Model : ViewModel에서 사용할 데이터를 정의합니다. 데이터는 DB에서 받아올 수도 있으며 필요한 데이터를 정의할 수 도 있습니다.

 

MVVM 구조에 관한 설명은 간단하게 마치고 실제 코드를 보면서 자세하게 확인해보겠습니다.


WPF 프로젝트 생성
.NET 5.0

먼저 프로젝트를 작성해줍니다.

템플릿에서 WPF 어플리케이션을 선택한 후에 대상 프레임워크는 .NET 5.0으로 선택해주세요.

5.0으로 선택하는 이유는 후에 포스팅하도록 하겠습니다!

 

폴더 만들기1
폴더 만들기2

이제 Model과 ViewModel을 담을 폴더를 생성해줍니다. 이 폴더안에 .cs 파일을 생성하여 프로젝트를 관리할 예정입니다.

 

클래스 생성
생성완료

만든 폴더의 아래에 Model과 ViewModel을 생성합니다. 각각의 파일은 위에 표시된 것처럼 클래스파일로 만들어주세요!

여기서 만든 파일에 데이터와 UI에서의 동작이 정의될 예정입니다.

 

간단한 UI

간단하게 UI를 구성해줍니다. 구성하는 방법은 화면 왼쪽의 도구상자에서 Lable을 끌어서 제목 3개를 만들어줍니다.

 

그 다음으로는 TextBox를 선택하여 제목아래에 하나씩 배치합니다.

 

이 프로젝트는 MVVM을 사용한 Data Binding을 알아보기 위한 프로젝트로 입력된 숫자에 2를 곱해서 결과로 출력하도록 할 것입니다.

 


먼저 필요한 데이터를 정의할 Model을 구성해보겠습니다.

 

Model 구현

Model을 구현하기 위해서 필요한 것이 있습니다.

using System.ComponentModel; 를 입력하여 INotifyPropertyChanged 를 상속받습니다.

위의 화면을 보시면 class MainModel : INotifyPropertyChanged 로 작성되어 있는 것을 확인할 수 있습니다.

하지만 필요한 인터페이스가 구현되어 있지 않기때문에 오류가 발생합니다. 여기서 alt+enter를 눌러서 인터페이스를 구현해줍니다.

 

구현

인터페이스를 구현하면 public event PropertyChangedEventHandler PropertyChanged; 가 자동으로 작성될텐데요.

 

여기서 아래에 있는 함수를 작성합니다.

 

이 함수는 데이터를 UI에 바인딩했을 때 실시간으로 업데이트하기 위해서 사용됩니다. 프로젝트를 완성하며 자세히 설명하겠습니다.

 

        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }

이제 실제로 다룰 변수를 정의하겠습니다!

namespace WPF_Project.Model
{
    class MainModel : INotifyPropertyChanged
    {
        private int num=1;

        public int Num
        {
            set
            {
                num = value;
                Num2 = value * 2;
                OnPropertyChanged("Num");

            }
            get
            {
                return num;
            }
        }

        private int num2=1;

        public int Num2
        {
            get 
                { 
                    return num2; 
                }
            set 
                { 
                    num2 = value; 
                    OnPropertyChanged("Num2"); 
                }
        }


        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }

    }
}

먼저 전체 코드를 적고 자세히 보겠습니다.

 

        private int num=1;

        public int Num
        {
            set
            {
                num = value;
                Num2 = value * 2;
                OnPropertyChanged("Num");

            }
            get
            {
                return num;
            }
        }

위를 보시면 private 변수인 num과 public변수인 Num을 볼 수 있습니다.

 

여기서 public 변수인 Num을 통해서 외부에서 private 변수인 num으로 접근할 수 있습니다.

 

그러므로 ViewModel이나 View에서 사용할 때는 항상 Num을 통해서 값을 저장하거나 받아올 수 있습니다.

 

Num의 속성을 보면 Num에 값을 입력하면 num에 그대로 저장되지만, Num2에는 입력된 값에 2를 곱해서 입력되는 것을 볼 수 있습니다.  이를 통해서 ViewModel이나 View에서 입력된 값에 2를 곱하여 출력되는 것입니다.

 

OnPropertyChanged("Num");

이 함수는 위에서 정의한 함수입니다.

이 함수는 UI에 바인딩된 변수가 변경되었을 때 UI를 업데이트할 수 있도록 알려주는 함수입니다.

함수에는 사용된 변수의 이름을 String 형식으로 써줍니다. 

 

같은 방식으로 Num2도 구성해줍니다.

 


이제 ViewModel을 구성해보겠습니다.

namespace WPF_Project.ViewModel
{
    class MainViewModel : INotifyPropertyChanged
    {
        private Model.MainModel model = null;
        public MainViewModel()
        {
            model = new Model.MainModel();
        }
        public Model.MainModel Model
        {
            get { return model; }
            set { model = value; OnPropertyChanged("Model"); }
        }


        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
    }
}

먼저 코드 전문을 작성하고 설명하겠습니다.

 

여기서도 INotifyPropertyChanged 를 상속받아 작성합니다.

 

이번 프로젝트에는 버튼동작이 없기 때문에 뷰모델에서 작성할 것이 많지 않습니다.

 

Private로 Mainmodel의 객체를 생성해줍니다. 또한, 이 객체에 접근하여 값을 다룰 public 변수를 선언하여 위에서 설명한 Num과 같이 Get,Set을 설정합니다.

 

이제 ViewModel과 Model의 구성은 모두 끝났습니다. 이제 View 단에서 ViewModel의 데이터를 바인딩해보겠습니다.

 


먼저 해야할 일은 View에 DataContext를 지정해주는 것입니다.

이 과정을 통해서 View와 ViewModel을 연결하게 됩니다. 이 과정을 거쳐야 ViewModel의 값을 View에 바인딩할 수 있기 때문에 중요한 과정입니다.

 

DataContext

지정하는 방법은 여러가지가 있지만 가장 알기 쉬운 방법으로 하겠습니다.

 

먼저 View의 Window를 클릭하신 후에 오른쪽 아래의 속성을 확인해봅니다.

 

잘 살펴보시면 사진에 표시된 것처럼 DataContext가 있을텐데, 여기서 새로만들기를 클릭합니다.

 

여기서 위에서 만들어두신 MainViewModel을 선택하고 확인을 누릅니다.

 

이제 View에 데이터를 바인딩할 준비가 모두 끝났습니다.

 

<TextBlock HorizontalAlignment="Center" Margin="0,39,0,0" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="24" FontWeight="Normal"><Run Language="ko-kr" Text="간단하게 숫자 바꾸기"/></TextBlock>
        <TextBox Margin="148,167,572,0" Text="{Binding Model.Num,UpdateSourceTrigger=PropertyChanged}" TextWrapping="Wrap" Height="24" VerticalAlignment="Top"/>
        <TextBlock HorizontalAlignment="Left" Margin="523,106,0,0" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="24" FontWeight="Normal" Width="102" Text="숫자결과 " Height="34"/>
        <TextBlock HorizontalAlignment="Left" Margin="136,106,0,0" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="24" FontWeight="Normal" Width="102" Text="숫자입력" Height="34"/>
        <TextBox Margin="535,167,185,0" Text="{Binding Model.Num2,UpdateSourceTrigger=PropertyChanged}" TextWrapping="Wrap" Height="24" VerticalAlignment="Top"/>

XAML코드를 확인해보겟습니다. 

 

코드를 보시면 TextBox코드에 Text="{Binding ~~}"로 된 부분을 볼 수 있습니다. 여기서 ViewModel에서 생성한 객체의 변수를 텍스트박스에 바인딩하여 표시하는 것입니다.

 

그 뒤에 UpdateSourceTrigger=PropertyChanged 는 텍스트박스에 바인딩된 변수가 바뀌게되면 UI를 바로 업데이트 해주는 설정입니다.

 

코드는 모두 작성이 끝났고 결과를 확인해보겠습니다.

 


프로그램 결과

위와 같이 숫자를 입력하면 입력한 숫자에 2가 곱해진 결과가 표시되는 것을 볼 수 있습니다.

 

간단한 프로그램이지만 WPF와 MVVM에 대한 기본적인 개념을 확인할 수 있었습니다.

 

처음 접하시는 분들에게는 생소한 개념이 많을 것이라고 생각됩니다.

 

하지만 MVVM이라는 패턴의 전체적인 흐름을 잘 생각해보시면 이해가 보다 쉬울 것입니다.

 

저도 배우는 과정에 있어 잘 알지는 못하지만, 궁금한 것을 남겨주시면 같이 이야기해보고 싶습니다.

 

감사합니다!

반응형

댓글