1.3.1 예제 - MVVM Source Generator
1️⃣ 학습 목표
: 예제의 학습 목표와 동작 시나리오를 파악한 뒤, 소스코드를 직접 확인합니다.
✔️ 1. 학습 목표
- CommunityToolkit.Mvvm 패키지를 사용한 간단한 프로젝트를 구현합니다.
- Source Generator가 자동 구현해주는 소스코드를 확해봅니다.
✔️ 2. 동작 시나리오

- 텍스트 박스에 '문자열' 입력
- 버튼 클릭
- 메시지 박스에 "Hello, {입력한 문자열}!" 출력
✔️ 3. 소스코드
2️⃣ Ex01SourceGenerator
: CommunityToolkit.Mvvm 패키지를 활용해 간단한 프로젝트를 단계별로 따라하며 구현해봅니다.
📁 1. 아래 링크를 참고해 WPF 프로젝트를 생성 합니다.
WPF 프로젝트 생성하기
01. Visual Studio 실행더보기 02. 새 프로젝트 생성더보기❶ 최근 실행한 프로젝트의 목록을 보여줍니다.❷ GitHub, Azure, DevOps, Bitbucket 등 원격 저장소에서 프로젝트를 가져옵니다.❸ 내 컴퓨터의 로컬
basiclike.tistory.com
📁 2. 생성한 WPF 프로젝트에 CommunityToolkit.Mvvm 패키지를 설치합니다.
02. 패키지 설치 방법
1️⃣ "NuGet 패키지 관리자"에서, CommunityToolkit.Mvvm 설치하는 방법더보기 WPF 프로젝트 생성하기01. Visual Studio 실행더보기 02. 새 프로젝트 생성더보기❶ 최근 실행한 프로젝트의 목록을 보여줍니다.
basiclike.tistory.com
📁 3. 프로젝트 구조
Ch01_Sec03_Ex01SourceGenerator/
├── ViewModels/
│ ├── MainViewModel.cs
├── Views/
│ ├── MainWindow.xaml
│ └── MainWindow.xaml.cs
├── App.xaml
└── App.xaml.cs
📁 4. ViewModel 클래스 만들기

①ViewModels 폴더에, MainViewModel.cs를 생성하고
②아래 소스코드를 붙여넣으면,
③관련 라이브러리가 자동 참조됩니다.
public partial class MainViewModel : ObservableObject
{
[ObservableProperty]
private string? userName;
[RelayCommand]
private void ShowGreeting()
{
MessageBox.Show($"{UserName}님, 안녕하세요.!");
}
}
📁5. View 화면 구성

④Views 폴더 아래에, MainWindow.xaml을 이동시킵니다.(또는 새로운 MainView를 생성합니다.)
⑤아래 XAML 코드를 붙여넣고, xmlns를 본인 프로젝트의 ViewModel 경로로 지정합니다.
xmlns:vm="clr-namespace:WPF_ToolKit01.ViewModel"
Title="Toolkit.MVVM Example" Height="200" Width="300">
<Window.DataContext>
<vm:MainViewModel />
</Window.DataContext>
<StackPanel Margin="20">
<TextBox Text="{Binding UserName, UpdateSourceTrigger=PropertyChanged}" />
<Button Content="Greet"
Command="{Binding ShowGreetingCommand}"
Margin="0,10,0,0"/>
</StackPanel>
📁6. App 수정

⑤App.Xaml 에서 시작 View 경로를, ⑥ViewModel 폴더로 이동시킨 MainWindow로 변경합니다.
3️⃣ 예제 자세히 살펴보기
: 프로젝트 소스코드의 의미를 주석을 통해 파악하고, 기능과 동작 구조를 자세히 이해합니다.
✔️ ViewModel 라이브러리
using CommunityToolkit.Mvvm.ComponentModel; // MVVM에서 속성 변경 알림(INotifyPropertyChanged)을 지원하는 기본 클래스 제공
using CommunityToolkit.Mvvm.Input; // ICommand 구현을 쉽게 하기 위한 특성(Attribute) 지원
using System.Windows; // WPF의 기본 UI 요소(MessageBox 등) 사용을 위해 필요
*소스코드를 추가하면, 필요한 라이브러리가 자동으로 추가되어 참조 할 수 있습니다.
✔️ ViewModel 소스코드
// ViewModel 클래스는 ObservableObject를 상속하여 속성 변경 알림 기능을 자동으로 제공
// partial 키워드를 사용하는 이유:
// - Source Generator가 자동으로 생성하는 코드(예: UserName 속성, ShowGreetingCommand 명령)를
// - 동일 클래스 이름의 다른 partial 파일로 분리하여 추가할 수 있게 해줌
// - 즉, 수동 작성 코드와 자동 생성 코드를 분리하여 관리 가능하게 함
public partial class MainViewModel : ObservableObject
{
// [ObservableProperty]는 다음과 같은 코드를 자동 생성해줌:
// public string UserName
// {
// get => userName;
// set => SetProperty(ref userName, value);
// }
// 또한, 속성 변경 시 INotifyPropertyChanged 이벤트를 발생시킴
[ObservableProperty]
private string userName; // 사용자 이름을 저장할 속성 (자동으로 UserName 속성 생성됨)
// [RelayCommand]는 다음과 같은 코드를 자동 생성해줌:
// public ICommand ShowGreetingCommand => new RelayCommand(ShowGreeting);
// 즉, 이 메서드를 바탕으로 ICommand를 구현한 명령 속성이 자동 생성됨
// 이 명령은 XAML에서 버튼 클릭과 같은 이벤트에 바인딩할 수 있음
[RelayCommand]
private void ShowGreeting()
{
// 사용자 이름을 포함한 환영 메시지를 MessageBox로 표시
MessageBox.Show($"Hello, {UserName}!");
}
}
✔️ 어트리뷰트와 자동 구현된 기능:
- [ObservableProperty]: INotifyPropertyChanged 구현부 자동 생성
- UserName 속성 + OnPropertyChanged 호출
- [RelayCommand]: ICommand 구현부 자동 생성
- ShowGreetingCommand 명령 생성 (사용자 정의한 ShowGreeting에 의해)
✔️ XAML 화면 구성
<!-- 태그(< >꺽쇠기호 내부)안에는 아래 주석 추가가 불가능합니다. -->
<!-- WPF 기본 UI 요소를 위한 XML 네임스페이스 -->
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
<!-- 디자인 타임 지원 (Blend 등에서 사용) -->
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
<!-- 현재 프로젝트의 기본 네임스페이스 -->
xmlns:local="clr-namespace:WpfApp"
<!-- ViewModel 클래스가 위치한 네임스페이스 -->
xmlns:vm="clr-namespace:WpfApp.ViewModels"
<!-- 윈도우 제목 및 크기 설정 -->
Title="Toolkit.MVVM Example" Height="200" Width="300">
<Window.DataContext>
<vm:MainViewModel />
<!-- ViewModel 인스턴스를 XAML의 DataContext로 설정 -->
</Window.DataContext>
<StackPanel Margin="20">
<!-- 수직 방향으로 자식 요소를 배치하는 레이아웃 컨트롤 -->
<!-- TextBox는 ViewModel의 UserName 속성과 양방향 바인딩됨 -->
<!-- UpdateSourceTrigger=PropertyChanged : 텍스트가 바뀔 때마다 즉시 ViewModel로 전달 -->
<TextBox Text="{Binding UserName, UpdateSourceTrigger=PropertyChanged}" />
<!-- Button 클릭 시 ViewModel의 ShowGreetingCommand 명령을 실행 -->
<!-- Margin="0,10,0,0"은 위쪽 여백을 줘서 간격 확보 -->
<Button Content="인사" Command="{Binding ShowGreetingCommand}" Margin="0,10,0,0"/>
</StackPanel>
</Window>