[C# WPF] MVVM 간단하게 시작하기 - 2 (버튼, 버튼커맨드)

반응형

오늘은 MVVM에서 버튼을 클릭했을 때,  함수를 실행시킬 수 있는 커맨드를 작성해보겠습니다.

 

이전의 글에서는 데이터 바인딩을 통해 숫자가 입력되면 자동으로 입력된 숫자에 2가 곱해져 출력되지만 이번 글에서는 버튼 클릭을 통해서 출력되도록 해볼 것입니다.

 


1. View

UI

먼저 간단하게 UI를 만들어보겠습니다. UI는 이전 글에서 작성했던 것과 동일하지만 버튼을 놓고 버튼의 컨텐츠를 바꾸어주었습니다.

 

사실, View의 버튼을 동작시키기 위해서 XAML상에서 해야할 작업이 있지만 ViewModel과 Model을 수정한 후에 다시 돌아와서 진행하겠습니다.

 

 


2. 커맨드

 

MVVM패턴에서 버튼을 사용하기 위해서는 Command 클래스를 따로 정의하여 사용합니다. (물론 필수인 것은 아니지만 반복해서 사용하는 것이기 때문에 클래스로 만들어 편리하게 사용하는 것이 좋습니다.)

 

먼저 클래스를 생성해보겠습니다.

 

클래스 생성
상속

Command 클래스는 기존에 제공해주는 ICommand 클래스를 상속받아 구성합니다.

 

하지만 클래스를 사용하기 위해서 필요한 것이 적용되어 있지않기 때문에 alt+enter을 통해서 using을 만듭니다.

클래스 구성

위의 과정을 마쳐도 구성요소를 구현하지 않아 오류가 발생할 것입니다.

 

이 과정을 자세히 보는 것도 좋지만 간단하게 의미를 먼저 보기 위해서 전문 코드를 보며 내용을 확인해보겠습니다.

 

    public class Command : ICommand
    {
        Action<object> ExecuteMethod;
        Func<object, bool> CanexecuteMethod;

        public Command(Action<object> execute_Method, Func<object, bool> canexecute_Method)
        {
            this.ExecuteMethod = execute_Method;
            this.CanexecuteMethod = canexecute_Method;
        }

        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {
            return true;
        }

        public void Execute(object parameter)
        {
            ExecuteMethod(parameter);
        }


    }

커맨드 클래스의 생성자를 보시면 execute_Method와 canexecute_Method가 있습니다.

 

execute_Method는 Action으로 버튼에 바인딩된 커맨드가 실제로 실행할 함수라고 생각하시면 됩니다.

 

canexecute_Method는 Action이 수행되기 전에 필요한 조건을 검사하는 메소드로 일반적으로는 true를 반환하는 bool형 메소드를 사용합니다.

 

간단하게 보면 커맨드 클래스는 실제로 실행할 메소드실행 전의 조건을 검사하는 메소드로 나누어져있다고 보면 편할 것같습니다!

 


3. Model

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

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

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

        public int Num
        {
            set
            {
                num = value;
                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));
            }
        }

    }
}

이번의 모델은 값을 반환하고 입력하는 과정만 담고있습니다.

 

public형 Num을 통해서 private형 num에 접근하는 형식입니다. (이전 글을 참고해주시면 감사하겠습니다.)

 

https://esound.tistory.com/10

 

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

MVVM, Model - View - ViewModel WPF에서 사용할 수 있는 디자인패턴입니다. 이번 글과 앞으로 이어지는 글에서 MVVM을 쉽고 간단하게 사용할 수 있도록 공부하며 배운 내용을 정리하겠습니다. View : 사용자

esound.tistory.com

 


4. ViewModel

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

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

        private void Execute_func(object obj)
        {
            model.Num2 = model.Num * 2;
        }

        private bool CanExecute_func(object obj)
        {
            return true;
        }

        public event PropertyChangedEventHandler PropertyChanged;

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

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

 

Model을 객체로 선언하여 변수에 접근하는 것은 이전의 글과 동일합니다.

 

다른 점은 버튼을 사용하기 위해서 위에서 생성한 Command 클래스를 사용하고 있다는 점입니다.

 

먼저 Command형 객체 btn_cmd를 생성해주었습니다. 버튼에 할당하기 위해 이름을 지었습니다.

 

그 후의 생성자에서 객체에 실행할 메소드와 조건을 할당하였습니다.

 

저는 입력한 숫자(Num)의 값에 2를 곱해서 출력(Num2)에 표시하기 위해서 Execute_func 메소드를 작성하였습니다. 

 

메소드 안에는 생성한 model 객체의 멤버에 접근하여 값을 다루도록 하였습니다.

 


 

4. View(XAML Binding)

사실 View는 위에서 다뤘고 이렇게 표현하는 것이 맞는지는 모르겠지만 클래스와 ViewModel 등을 구현한 후에 버튼에 커맨드를 바인딩 하기 위해 돌아왔습니다.

 

        <Button Content="숫자 바꾸기" Command="{Binding btn_cmd}" HorizontalAlignment="Left" Margin="324,162,0,0" VerticalAlignment="Top" Height="34" Width="106"/>

사실 간단합니다. 버튼에 Command를 할당한 후에 ViewModel에서 선언한 btn_cmd를 바인딩하는 것이 끝입니다.

 

이 것을 통해서 버튼이 눌리면 btn_cmd가 실행되고 실행조건은 무조건 true를 반환하기 때문에 입력된 숫자에 2가 곱해진 값이 출력되는 것입니다

 


WPF MVVM패턴의 버튼 바인딩에 대해 간단하게 알아보았습니다.

 

Winform의 경우에는 간단하게 버튼이벤트를 만들 수 있지만 MVVM패턴에서는 귀찮은 과정을 거쳐야합니다.

 

하지만 WPF를 사용하는 것에 있어서는 필요한 방법 중 하나이기 때문에 알아두는 것이 좋다고 생각합니다.

 

감사합니다!

반응형