안녕하세요!
이번 글에서는 WPF 예제 프로젝트를 통해 WPF에서 사용되는 디자인 패턴 중 하나인 MVVM패턴을 알아보도록 하겠습니다.
디자인 패턴은 소프트웨어 개발에서 반복적으로 발생하는 문제를 해결하기 위한 일종의 설계 템플릿이라고 할 수 있습니다.
이러한 패턴들은 이전에 검증된 해결책을 제공하여 개발자들이 특정 문제를 효과적으로 해결할 수 있도록 도와줍니다.
디자인 패턴은 코드의 구조와 관련이 있으며, 코드의 가독성, 재사용성 및 유지보수성을 개선하는 데 도움을 줄 수 있습니다.
프로젝트 생성
MVVM프로젝트를 생성해 줍니다.
RelayCommand클래스 생성
[솔루션탐색기] → [프로젝트 우클릭] → [추가] → [새 항목] → [클래스] 를 통해 RelayCommand 클래스를 생성해 줍니다.
RelayCommand.cs 코드작성
namespace MVVM
{
public class RelayCommand : ICommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public RelayCommand(Action execute, Func<bool> canExecute = null)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return _canExecute == null || _canExecute();
}
public void Execute(object parameter)
{
_execute();
}
}
}
- ICommand 인터페이스를 상속받아 ViewModel에서 내린 명령이 수행 가능한지 여부를 판단하고 실행하게 됩니다.
ViewModel클래스 생성
[솔루션탐색기] → [프로젝트 우클릭] → [추가] → [새 항목] → [클래스] 를 통해 ViewModel클래스를 생성해 줍니다.
ViewModel클래스 작성
namespace MVVM
{ public class ViewModel : INotifyPropertyChanged
{
private string _greeting;
public string Greeting
{
get { return _greeting; }
set
{
_greeting = value;
OnPropertyChanged(nameof(Greeting));
}
}
private string _buttonText;
public string ButtonText
{
get { return _buttonText; }
set
{
_buttonText = value;
OnPropertyChanged(nameof(ButtonText));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public ViewModel()
{
Greeting = "안녕하세요, MVVM 예제입니다!";
ButtonText = "인사 변경";
ChangeGreetingCommand = new RelayCommand(ChangeGreeting);
}
public ICommand ChangeGreetingCommand { get; private set; }
private void ChangeGreeting()
{
Random random = new Random();
string[] greetings = { "안녕하세요!", "Hello!", "Hola!", "Bonjour!" };
int randomIndex = random.Next(greetings.Length);
Greeting = greetings[randomIndex];
}
}
}
- INotifyPropertyChanged 인터페이스를 구현하여 속성 값이 변경될 때 View에 알리고 데이터 바인딩을 통해 UI를 업데이트 해주는 일종의 중계자 역할을 하는 클래스 입니다.
- PropertyChangedEventHandler에 의해 프로퍼티가 변경되면 xaml에서 바인딩 받는 프로퍼티에 적용됩니다.
메인윈도우 XAML코드 작성
<Window x:Class="MVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MVVM"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="{Binding Greeting}" FontSize="20" FontWeight="Bold" Margin="0,0,0,10"/>
<Button Content="{Binding ButtonText}" Width="100" Height="30" Command="{Binding ChangeGreetingCommand}"/>
</StackPanel>
</Grid>
</Window>
- TextBlock의 Text속성을 ViewModel 내부 Greeting으로 바인딩하였습니다.
- Button의 Text속성과 Command도 ViewModel을 참조하여 바인딩하고 있습니다.
- 어플리케이션 실행 중에 메모리에 있는 값을 참조하여 텍스트를 참조하기 때문에, 실행 전 디자인뷰에서는 글자가 보이지 않습니다.
MainWindow.xaml비하인드코드 수정
namespace MVVM
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private ViewModel _viewModel;
public MainWindow()
{
InitializeComponent();
//ViewModel객체 생성
_viewModel = new ViewModel();
//DataContext연결
DataContext = _viewModel;
}
}
}
- ViewModel객체를 생성하고, DataContext에 객체를 연결해 주었습니다.
빌드
빌드 후 버튼을 누르면 ViewModel 클래스에서 정의한 랜덤 인삿말이 출력되게 됩니다.
여기까지 WPF에서 사용되는 디자인 패턴 중 하나인 MVVM패턴을 예제 프로젝트를 통해 알아보았습니다.
이번 예제 프로젝트는 [ControlHandling] 포스팅에서 다뤘던 프로젝트와 기능은 동일하지만 다른 구조를 가지고 있습니다.
프로젝트의 구조는 개발 시간과 추후 유지보수에 많은 영항을 끼치기 때문에 개발 전 알맞는 구조를 설계하는것이 중요합니다.
저번 포스팅과 코드의 구조를 비교해 보세요!
[C#] WPF : Control Handling
안녕하세요! 이번 글에서는 WPF 프로젝트를 생성 후 메인윈도우에 배치한 컨트롤을 비하인드 코드에서 핸들링하는 방법에 대해 알아보겠습니다. 예제는 버튼을 클릭하면 텍스트 블록에 랜덤한
lee-coder.tistory.com
감사합니다!
'[C#] > WPF' 카테고리의 다른 글
[C#] WPF : 리소스 사전 (15) | 2023.09.05 |
---|---|
[C#] WPF : Graphic (31) | 2023.08.21 |
[C#] WPF : Control Handling (22) | 2023.08.17 |
[C#] WPF : XAML (37) | 2023.08.10 |
[C#] WPF : 프로젝트 생성 (24) | 2023.08.09 |