Home C#WPF [WPF] ViewModel

[WPF] ViewModel

by DUBUKIMCH

ViewModel 개념

ViewModel은 MVVM(Model-View-ViewModel) 패턴에서 중요한 구성 요소로, View(UI)와 Model(비즈니스 로직 및 데이터) 사이의 중재자 역할을 합니다. ViewModel은 뷰가 데이터에 접근하고 이를 표시할 수 있도록 데이터를 제공하며, 사용자 입력을 처리하여 모델에 전달합니다. 또한, ViewModel은 데이터 바인딩을 지원해 뷰와 데이터가 자동으로 동기화되도록 합니다.

ViewModel의 주요 특징:

  • 데이터 바인딩: View와 데이터 소스 간의 연결을 제공합니다.
  • 상태 관리: 뷰에 필요한 상태를 관리하고 변경 사항을 뷰에 알립니다.
  • 명령 처리: 버튼 클릭 등의 사용자 명령을 처리합니다.
  • 독립성: ViewModel은 View에 대한 참조가 없으므로, 뷰의 변경이 ViewModel에 영향을 미치지 않습니다.

ViewModel의 활용 방법

  1. INotifyPropertyChanged 구현: ViewModel은 속성 변경 시 뷰에 알리기 위해 INotifyPropertyChanged 인터페이스를 구현해야 합니다.
  2. 명령 처리: ICommand 인터페이스를 사용해 뷰에서 발생하는 명령(버튼 클릭 등)을 처리합니다.

예제 코드: 기본적인 ViewModel

이 예제에서는 Name 속성의 값을 입력받아 버튼 클릭 시 메시지를 표시하는 간단한 ViewModel을 보여줍니다.

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 클래스

RelayCommandICommand 인터페이스의 간단한 구현으로, 명령의 실행과 실행 가능 여부를 정의합니다.

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 (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>

View 연결 (Code-behind)

using System.Windows;

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

실행 결과

코드 설명:

  • MainViewModel 클래스: Name 속성은 뷰에 바인딩되고, 변경될 때 PropertyChanged 이벤트가 발생해 뷰가 업데이트됩니다.
  • ShowNameCommand: 버튼 클릭 시 ShowName() 메서드를 호출해 메시지를 표시합니다.
  • RelayCommand: 명령 실행을 위한 클래스입니다. Action 델리게이트를 통해 실행할 동작을 전달받고, Execute() 메서드에서 실행합니다.
  • INotifyPropertyChanged: OnPropertyChanged() 메서드가 속성 값 변경 시 호출되어 뷰가 자동으로 갱신됩니다.

이 예제는 MVVM 패턴에서 ViewModel이 어떻게 뷰와 데이터를 연결하고 사용자 명령을 처리하는지를 보여줍니다. ViewModel을 활용하면 코드가 UI에 종속되지 않아 테스트와 유지보수가 용이해집니다.

You may also like

Leave a Comment

error: Content is protected !!