포스트

그래서 MVVM 패턴이 뭔데? (Winform vs WPF)

CommunityToolkit.Mvvm

그래서 MVVM 패턴이 뭔데? (Winform vs WPF)

Winform 만 사용했었다가 WPF 사용하면서 MVVM 패턴을 처음 알게되었다.

Winform vs WPF (MVVM)

간단한 버튼 클릭 예제여도 두 방법은 확연히 차이 난다.

윈도우에 버튼을 만들고 버튼을 누르면 버튼 텍스트가 바뀌는 예제를 만들어보았다.

Winform 버튼 예제

Winform Button Example UI

버튼을 더블 클릭하여 코드로 진입

1
2
3
4
private void button1_Click(object sender, EventArgs e)
{
    button1.Text = "Clicked!";
}

MVVM 을 이용한 WPF 버튼 예제

WPF MVVM Example UI

1
2
<Button Content="Button"
        Width="150" Height="100"/>

버튼을 더블 클릭하면 Winform 과 똑같아진다.

그러면 MVVM 패턴은 어떻게 사용하는가?

버튼 클릭 이벤트를 받으려면 Button 의 Command 라는 속성을 이용 해야 한다.
Command 를 사용하기 위해서는 ICommand 를 상속받는 클래스 구현이 필요하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class RelayCommand : ICommand
{
	private readonly Action<object?> _execute;
	private readonly Func<object?, bool>? _canExecute;
	
	public RelayCommand(Action<object?> execute, Func<object?, bool>? canExecute = null)
	{
		_execute = execute ?? throw new ArgumentNullException(nameof(execute));
		_canExecute = canExecute;
	}
	
	public event EventHandler? CanExecuteChanged;
	
	public bool CanExecute(object? parameter)
	{
		return _canExecute?.Invoke(parameter) ?? true;
	}
	
	public void Execute(object? parameter)
	{
		_execute(parameter);
	}
	
	public void RaiseCanExecuteChanged()
	{
		CanExecuteChanged?.Invoke(this, EventArgs.Empty);
	}
}

자! 이제 ViewModel 에서 CommandButton Text 속성을 만들어 준다. 또한, 버튼 텍스트가 바뀔 때마다 UI 에 알려줄 PropertyChanged Event 를 등록한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class MainViewModel : INotifyPropertyChanged
{
	private string buttonText = "Button";
	public string ButtonText
	{
		get { return buttonText; }
		set { buttonText = value; OnPropertyChanged(); }
	}

    public ICommand? ButtonClickCommand { get; set; }

    public MainViewModel()
    {
        ButtonClickCommand = new RelayCommand(ButtonClick);
    }

    private void ButtonClick(object? obj)
    {
        ButtonText = "Clicked!";
    }

    public event PropertyChangedEventHandler? PropertyChanged;
    public void OnPropertyChanged([CallerMemberName] string? propertyName = null)
	{
		this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
	}
}

이제 모든 준비가 끝나… … 지 않았다. View 를 ViewModel 과 연동시켜주어야한다.

MainWindow.xaml.cs 에서

1
2
3
4
5
public MainWindow()
{
    InitializeComponent();
    this.DataContext = new MainViewModel();
}

DataContextViewModel 을 연결해주어야 한다.

이제 모든 준비가 끝나… 아직이다.. ViewButton 속성에서 ViewModel 에 있는 속성과 연동 시켜주어야 한다.

1
2
3
<Button Content="{Binding ButtonText}"
        Command="{Binding ButtonClickCommand}"
        Width="150" Height="100"/>

이제 진짜 모든 준비가 끝났다.

실행하여보자.

버튼을 누를 때 버튼 텍스트가 변하는 것을 볼 수 있다.

  1. RelayCommand 클래스 작성
  2. ViewModel 에서 속성 작성
  3. View - ViewModel 연결(DataContext)
  4. View 에서 ViewModel 의 속성과 연결

정말 간단한 버튼 예제였음에도 불구하고 WPF MVVM 방식은 오래 걸리고 복잡했다.

그럼에도 불구하고 왜 MVVM 을 사용할까?

  • View 와 ViewModel 을 끊고 단독적으로 사용할 수 있다.
  • View 가 달라도 Winform 에서 작성한 코드를 또 작성할 필요없이 ViewModel 을 연결만하면 사용 가능하다.
  • View 와 ViewModel 독립적으로 코딩이 가능하다.

=> View 와 ViewModel 을 독립적으로 사용 가능하다.

그리고 다시 한번 MVVM 패턴이란? 포스트를 읽어 보자.

C# 은 Nuget Package 가 정말 다양한 걸로 유명한데 이 복잡한 MVVM 패턴도 역시 쉽게 사용할 수 있는 Nuget 이 있다.

마이크로소프에서 지원하는 Community.Toolkit.Mvvm 마소니까 믿고 사용할 수 있다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.