Mvvm Sample for Winforms

Mvvm Sample for Winforms

이철우

2022년 11월에 출시한 마이크로소프社의 .Net 7 에서 Winforms 프로젝트가 MVVM 패턴을 지원하도록 몇 가지 변화가 있었다.[참고 1]

  • ButtonBase 클래스에 Command 속성 추가
  • ToolStripItem 클래스에 Command 속성 추가
  • Control 클래스에 DataContext 속성 추가

아래 그림은 Winforms 디자인 모드에서 Command를 묶는 것을 보여준다.[참고 2]


(그림1)

이 글에서는 글쓰이의 먼저 글 - MVVM Sample for Wpf[참고 3] - 을 기초로, .Net 8 Winforms 프로젝트에서 MVVM 패턴을 구현한다. 프로젝트 A를 만들고 CommunityToolkit.Mvvm 8.3.2를 참조로 넣는다.

[참고 3]의 Model.cs와 ViewModel.cs를 프로젝트 A에 넣는다.

프로젝트 A를 만들 때 생성된 Form1.cs를 다음처럼 바꾼다. 이 글에서는 묶음(Binding) 기능을 코드로 구현한다.

// Form1.cs

public partial class Form1 : Form
{
    private readonly ViewModel _viewModel;

    private readonly Panel _mainPanel;
    private readonly Panel _dataPanel;
    private readonly Panel _actionPanel;

    private readonly TextBox _textBoxData;
    private readonly Button _buttonReset;
    private readonly Button _buttonIncrease;

    public Form1()
    {
        InitializeComponent();

        _viewModel = new ViewModel(new Model());
        DataContext = _viewModel;

        _mainPanel = new Panel();
        _dataPanel = new Panel();
        _actionPanel = new Panel();

        _textBoxData = new TextBox();
        _buttonReset = new Button();
        _buttonIncrease = new Button();

        InitComponents();
    }

    private void InitComponents()
    {
        _mainPanel.SuspendLayout();
        SuspendLayout();

        var label = new Label
        {
            Text = "Data",
            Dock = DockStyle.Left
        };
        _textBoxData.Dock = DockStyle.Fill;
        _textBoxData.TextAlign = HorizontalAlignment.Right;
        _textBoxData.DataBindings.Add(new Binding("Text", DataContext, "Model.Data"));

        _dataPanel.Controls.Add(_textBoxData);
        _dataPanel.Controls.Add(label);

        _buttonReset.AutoSize = true;
        _buttonReset.Dock = DockStyle.Left;
        _buttonReset.Text = "Reset";
        _buttonReset.Command = _viewModel.ResetCommand;
        _buttonIncrease.AutoSize = true;
        _buttonIncrease.Dock = DockStyle.Left;
        _buttonIncrease.Text = "Increase";
        _buttonIncrease.Command = _viewModel.IncreaseCommand;

        _actionPanel.Controls.Add(_buttonReset);
        _actionPanel.Controls.Add(_buttonIncrease);

        _dataPanel.Height = 36;
        _dataPanel.Dock = DockStyle.Top;
        _actionPanel.Height = 36;
        _actionPanel.Dock = DockStyle.Top;

        _mainPanel.Controls.Add(_actionPanel);
        _mainPanel.Controls.Add(_dataPanel);

        Controls.Add(_mainPanel);
        _mainPanel.Dock = DockStyle.Fill;

        _mainPanel.ResumeLayout(false);
        _mainPanel.PerformLayout();
        ResumeLayout(false);
    }
}

(코드 1)

프로젝트 A를 빌드하고 실행한다.

이제 Winforms에서도 비지니스 로직과 UI를 WPF처럼 분리할 수 있다. Winforms에서 새로 더한 여러 Control들과 함께, 이 분리를 코드로 구현하면 많은 이점이 있을 것으로 생각한다. 한 예로 Winforms 디자인 모드에서 UI 속성을 바꾸는 것은 '재활용’에 불리한데, 이 문제를 없앨 수 있다.

[참고 1]
Windows Forms Binding Improvements in .NET 7 for MVVM Support

[참고 2]
What’s new in Windows Forms in .NET 7.0

[참고 3]
MVVM Sample for Wpf (고침)

7개의 좋아요