06. Generic Parameter
RelayCommand는 MVVM 구조에서 메서드(Logic)를 실행하는 방법 입니다.
CommandParameter는 RelayCommand에 "매개변수"를 전달해 메서드(Logic)를 실행하는 방법 입니다.
1️⃣ RelayCommand<T> 개요
📚 Microsoft Docs: RelayCommand<T> Generator

✔️ RelayCommand<T> 개요
- RelayCommand<T>는
View에서 ViewModel 메서드를 실행해야 할 때, 매개변수를 전달 하기 위해 사용합니다. - CommandParameter는
전달되는 인자의 타입을 명확히 지정할 수 있는 제네릭 버전의 명령(Command)입니다.
✔️ 왜 필요한가?
- CommandParameter="{Binding}"로 객체를 전달할 때,
- object로 받으면 명시적 형변환(cast) 필요합니다. 이는 런타임 오류 발생 가능성이 존재합니다.
- RelayCommand<T>로 받으면 컴파일 타임에 타입 검증이 가능하여 안전합니다.
✔️ 관련 네임스페이스
using CommunityToolkit.Mvvm.Input;
✔️ 소스코드
2️⃣ 01RelayCommand - 매개변수 없는, 간단한 RelayCommand 구현 예제
*CommunityToolkit.Mvvm 패키지 설치 후 진행해주세요.
✔️ 1. 동작 시나리오

- 사용자가 버튼을 클릭하면 HelloCommand가 실행되고 메시지 박스 출력
✔️ 2. [ RelayCommand ] 로 구현
📁 2.1 프로젝트 구조
RelayCommandDemo/
├── ViewModels/
│ └── MainViewModel.cs
├── MainWindow.xaml
└── MainWindow.xaml.cs
📁 2.2 ViewModel 클래스 만들기 (MainViewModel.cs)

public partial class MainViewModel : ObservableObject
{
[RelayCommand]
private void SayHello()
{
MessageBox.Show("안녕하세요! RelayCommand 버튼을 클릭했습니다.");
}
}
📁 2.3 XAML 화면 구성

xmlns:viewModels="clr-namespace:WPF_ToolKit09_01.ViewModels"
Title="RelayCommand Demo" Height="200" Width="300">
<Window.DataContext>
<viewModels:MainViewModel/>
</Window.DataContext>
<StackPanel Margin="20">
<Button Content="Say Hello"
Command="{Binding SayHelloCommand}"/>
</StackPanel>
✔️ 3. 결과
- 버튼을 클릭하면 SayHello() 메서드가 실행되어 메시지박스 출력
3️⃣ 02ICommandParameter - 자동완성 없이, C# MVVM 구현 구조 예제
✔️ 1. 학습 목표
- Step 1.
- CommunityToolkit.Mvvm 패키지를 통한 자동완성 기능을 학습하기에 앞서,
전통적인 방식의 C# MVVM 패턴 구현 방법을 되짚어 봅니다. - ICommand 인터페이스를 상속 구현한 RelayCommand 구현하고,
ViewModel 에서 메서드에 매개변수를 전달하는 방법을 되짚어봅니다.
- CommunityToolkit.Mvvm 패키지를 통한 자동완성 기능을 학습하기에 앞서,
- Step 2.
- 이후에 CommunityToolkit.Mvvm 패키지를 사용해 자동 구현할 때,
어떤 부분이 자동화되어 편리한지 확인합니다.
- 이후에 CommunityToolkit.Mvvm 패키지를 사용해 자동 구현할 때,
- Step 3.
- 그리고 프로젝트의 어느 부분에 적용하면 효과적일지 예상해봅니다.
✔️ 2. 동작 시나리오

1. 사용자가 TextBox에 이름 입력
↓
2. 버튼 클릭 → Command 실행
↓
3. CommandParameter 값 전달
↓
4. ViewModel 메서드에서 전달된 값 사용
// 이전 예제에서는, 두개의 프로퍼티를 사용해 View에 반영했습니다.
✔️ 3. 자동완성 없이, 전통적인 방식으로 C# MVVM 구조를 만들기 위해 ICommand 구현
📁 3.1 가장먼저, 아래 링크를 참고해 WPF 프로젝트를 생성 합니다.
WPF 프로젝트 생성하기
01. Visual Studio 실행더보기 02. 새 프로젝트 생성더보기❶ 최근 실행한 프로젝트의 목록을 보여줍니다.❷ GitHub, Azure, DevOps, Bitbucket 등 원격 저장소에서 프로젝트를 가져옵니다.❸ 내 컴퓨터의 로컬
basiclike.tistory.com
📁 3.2 생성한 WPF 프로젝트에, 아래 링크를 참고해 CommunityToolkit.Mvvm 패키지를 설치합니다.
02. 패키지 설치 방법
1️⃣ "NuGet 패키지 관리자"에서, CommunityToolkit.Mvvm 설치하는 방법더보기 WPF 프로젝트 생성하기01. Visual Studio 실행더보기 02. 새 프로젝트 생성더보기❶ 최근 실행한 프로젝트의 목록을 보여줍니다.
basiclike.tistory.com
📁 3.3 프로젝트 구조
WpfMvvmToolkit05_01ICommand/
├── Commands/
│ └── RelayCommand.cs
├── ViewModels/
│ └── MainViewModel.cs
└── Views/
└── MainWindow.xaml ← 메인 뷰
└── MainWindow.xaml.cs
📁 3.4 ICommandParameter 동작 구조

①ViewModel 네임스페이스를 ②View에 등록합니다. ③DataContext를 지정합니다.

④View에서 버튼을 클릭하면 ⑤바인딩 된 ⑥RelayCommand가 실행됩니다.
① RelayCommand는, MainViewModel 생성시 ②SayHello(Object params) 메서드가 등록되도록 구현되어
③ RelayCommand가 실행되면, 등록된 SayHello(Object params) 메서드가 동작합니다.
📁 3.5 ICommand 구현

public class RelayCommand : ICommand
{
private readonly Action<object?> _execute;
public RelayCommand(Action<object?> execute)
{
this._execute = execute;
}
public bool CanExecute(object? parameter) => true;
//.NET의 명시적 델리게이트 호출 메서드 .Invoke()를 사용가능하지만, 생략 사용 권장됨.
//public void Execute(object? parameter) => _execute.Invoke(parameter);
public void Execute(object? parameter) => _execute(parameter); // ← 가장 간결하고 일반적인 방식
public event EventHandler? CanExecuteChanged;
}
📁 3.6 ViewModel 구현하기

public class MainViewModel : INotifyPropertyChanged
{
private string? greeting;
public string? Greeting
{
get => greeting;
set
{
if (greeting != value)
{
greeting = value;
OnPropertyChanged();
}
}
}
public ICommand SayHelloCommand { get; }
public MainViewModel()
{
// CommandParameter 값을 받을 수 있는 명령 초기화
SayHelloCommand = new RelayCommand(SayHello);
}
private void SayHello(object? parameter)
{
// parameter는 버튼 클릭 시 전달된 CommandParameter입니다.
// parameter가 string 타입이면 true이고, 그 값을 name 변수에 담음
if (parameter is string name && !string.IsNullOrWhiteSpace(name))
Greeting = $"안녕하세요, {name}님!";
else
Greeting = "이름을 입력하세요!";
}
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null!) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
📁 3.7 View 구성하기

xmlns:vm="clr-namespace:WpfMvvmToolkit05_01ICommand.ViewModels"
Title="RelayCommand Demo" Height="200" Width="300">
<Window.DataContext>
<vm:MainViewModel />
</Window.DataContext>
<StackPanel Margin="20">
<TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"
Margin="0,0,0,10"/>
<Button Content="인사하기"
Command="{Binding SayHelloCommand}"
Margin="0,0,0,10"/>
<TextBlock Text="{Binding GreetingMessage}"
FontWeight="Bold" />
</StackPanel>
03. RelayCommandGeneric - RelayCommand <T> 사용 구조 예제
*CommunityToolkit.Mvvm 패키지 설치 후 진행해 주세요.
✔️ 1. 학습 목표
- " 매개변수 없는, 간단한 RelayCommand 구현 예제 " 및 이전 예들과 비교하여
사용할 때, 어떤 부분을 효과적으로 사용 할 수 있는지 확인합니다.
// PersonViewModel 클래스는 MVVM 패턴에서 ViewModel 역할을 수행합니다.
// ObservableObject를 상속받아 INotifyPropertyChanged를 자동으로 구현합니다.
using CommunityToolkit.Mvvm.ComponentModel;
public partial class PersonViewModel : ObservableObject
{
// private 필드(name)에 대해 자동으로 public 프로퍼티(Name)이 생성됩니다.
// 또한 프로퍼니가 변경될 때 INotifyPropertyChanged 인터페이스를 통해 UI에 반영되도록 합니다.
[ObservableProperty]
private string? name;
}
✔️ 동작 시나리오

- 텍스트 박스에 이름을 입력하고
- 버튼을 클릭하면
- "_ _ _님, 안녕하세요!" 메시지 출력
✔️ 2. [ RelayCommand ] 로 구현
📁 2.1 프로젝트 구조
RelayCommandDemo/
├── ViewModels/
│ └── MainViewModel.cs
├── MainWindow.xaml
└── MainWindow.xaml.cs
📁2.2 ViewModel 클래스 만들기 (MainViewModel.cs)

public partial class MainViewModel : ObservableObject
{
[ObservableProperty]
private string userName;
[RelayCommand]
private void Greet(string name)
{
MessageBox.Show($"{name}님, 안녕하세요!");
}
}
📁 2.3 XAML 화면 구성

xmlns:viewModels="clr-namespace:WPF_ToolKit09_02.ViewModel"
Title="RelayCommand<T> Demo" Height="200" Width="300">
<Window.DataContext>
<viewModels:MainViewModel/>
</Window.DataContext>
<StackPanel Margin="20">
<TextBox Text="{Binding UserName, UpdateSourceTrigger=PropertyChanged}" />
<Button Content="Greet"
Command="{Binding GreetCommand}"
CommandParameter="{Binding UserName}"/>
</StackPanel>
✔️ 3. 결과
- TextBox에 "홍길동" 입력 후 버튼 클릭 시, "홍길동님, 안녕하세요!" 출력
✔️ 비교 RelayCommand vs RelayCommand<T>
항목 | RelayCommand | RelayCommand<T> |
매개변수 | 없음 | 있음 |
사용 예 | 단순 버튼 처리 | 입력값 전달, 리스트 항목 선택 |
XAML CommandParameter | 필요 없음 | 필수 (값 바인딩) |
4️⃣ 예제 - RelayCommand<T> 동작 구조
✔️ 1. 예제의 RelayCommand<T> 살펴보기
public partial class MainViewModel : ObservableObject
{
[ObservableProperty]
private string userName;
[RelayCommand]
private void Greet(string name)
{
MessageBox.Show($"{name}님, 안녕하세요!");
}
}
✔️ 2. 자동 생성되는 코드

위처럼 작성하면 GreetCommand가 GreetCommand<String>으로 자동 생성됩니다.
이건 곧 IRelayCommand<String>를 통해 String 타입의 매개변수만 허용하는 명령이 됩니다.
✔️3. 작동 흐름
<Button Content="Greet"
Command="{Binding GreetCommand}"
CommandParameter="{Binding UserName}"/>
- (사용자가 TextBox에 이름 입력 → UserName 속성 업데이트)
- 사용자가 버튼을 클릭
- UserName 프로퍼티를 CommandParameter로
- ViewModel의 GreetCommand에 전달
- GreetCommand.Execute(UserName) → Greet(string name) 실행
✔️4. 추가 과제
- 객체 전달
- Person 객체를 매개변수로 전달하고, 로직에서 Name, Age 등 필드 사용
5️⃣ 예제 - IMultiValueConverter 복합 값 전달
✔️ ViewModel
[RelayCommand]
private void Submit((Person person, string comment) input)
{
var (person, comment) = input;
// 복합 정보 사용
}
✔️ View (XAML)
<Button Content="제출">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource TupleConverter}">
<Binding Path="." />
<Binding Path="CommentText" />
</MultiBinding>
</Button.CommandParameter>
</Button>