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
