» [WPF] MVVM 패턴

[WPF] MVVM 패턴

by DUBUKIMCH

MVVM(Model-View-ViewModel) 패턴은 주로 WPF, UWP, Xamarin.Forms 등에서 사용되는 소프트웨어 아키텍처 패턴으로, UI와 비즈니스 로직을 분리하여 코드의 유지 보수성과 확장성을 높이는 데 도움을 줍니다. 이 패턴은 MVC(Model-View-Controller)에서 발전된 형태로, 데이터 바인딩 기능을 활용해 뷰와 데이터의 동기화를 자동으로 관리합니다.

MVVM 구성 요소

  1. Model: 데이터와 비즈니스 로직을 담당하며, 주로 데이터 구조 및 데이터베이스와의 상호작용을 처리합니다.
  2. View: 사용자 인터페이스(UI)를 담당하며, XAML로 작성된 화면을 의미합니다.
  3. ViewModel: 뷰와 모델 간의 중간자 역할을 하며, 뷰의 데이터 바인딩을 통해 뷰와 상호작용합니다. ViewModel은 명령과 프로퍼티를 통해 뷰의 동작을 제어하고 데이터 상태를 유지합니다.

MVVM 예제 코드

이 예제는 간단한 MVVM 패턴의 구현으로, Name 속성에 입력한 값을 UI에 표시합니다.

Model (데이터 클래스)

public class Person
{
    public string Name { get; set; }
}

View (XAML)

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MVVM Example" Height="200" Width="400">
    <Grid>
        <StackPanel>
            <TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" Width="200" Margin="10"/>
            <Button Content="Show Name" Command="{Binding ShowNameCommand}" Width="100" Margin="10"/>
        </StackPanel>
    </Grid>
</Window>

ViewModel (뷰모델)

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;

public class MainViewModel : INotifyPropertyChanged
{
    private string _name;

    public string Name
    {
        get => _name;
        set
        {
            _name = value;
            OnPropertyChanged();
        }
    }

    public ICommand ShowNameCommand { get; }

    public MainViewModel()
    {
        ShowNameCommand = new RelayCommand(ShowName);
    }

    private void ShowName()
    {
        MessageBox.Show($"Hello, {Name}!");
    }

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

RelayCommand 클래스 (명령 구현)

using System;
using System.Windows.Input;

public class RelayCommand : ICommand
{
    private readonly Action _execute;
    private readonly Func<bool> _canExecute;

    public event EventHandler CanExecuteChanged;

    public RelayCommand(Action execute, Func<bool> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute == null || _canExecute();
    }

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

    public void RaiseCanExecuteChanged()
    {
        CanExecuteChanged?.Invoke(this, EventArgs.Empty);
    }
}

View 연결 (Code-behind)

using System.Windows;

namespace WpfApp
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainViewModel();
        }
    }
}

실행 사진

코드 설명:

  • Model: Person 클래스는 Name 속성만 포함하는 단순한 데이터 클래스입니다.
  • View: XAML 파일에서 TextBoxName 속성과 바인딩되고, ButtonShowNameCommand 명령과 바인딩됩니다.
  • ViewModel:
    • MainViewModel 클래스는 INotifyPropertyChanged 인터페이스를 구현하여 Name 속성 변경 시 뷰에 자동으로 알립니다.
    • ShowNameCommand는 버튼 클릭 시 ShowName() 메서드를 실행합니다.
  • RelayCommand: 간단한 명령을 생성하는 유틸리티 클래스로, ICommand 인터페이스를 구현하여 명령을 실행하고 상태를 확인할 수 있게 합니다.
  • View 연결: MainWindow에서 DataContextMainViewModel 인스턴스로 설정하여 뷰와 뷰모델을 연결합니다.

MVVM의 장점:

  • 유지보수성: 코드와 UI의 분리로 유지보수가 쉽습니다.
  • 테스트 용이성: 뷰모델이 로직을 포함하기 때문에 단위 테스트가 더 쉽습니다.
  • 재사용성: 뷰모델은 특정 뷰에 종속되지 않으므로 여러 뷰에서 재사용이 가능합니다.

이 예제를 통해 MVVM 패턴의 기본 구조와 동작 방식을 이해할 수 있습니다.

You may also like

Leave a Comment

error: Content is protected !!