1. 참고자료

더보기

✔️ Microsoft Learn / Learn / .NET / MVVM

공유한 링크는 .NET Community ToolkitObservableRecipient 클래스에 대한 문서입니다.

이 클래스는 ObservableObject와 IRecipient<TMessage>를 결합하여 만든 ViewModel 전용 수신자 기반 클래스입니다.

MVVM 아키텍처에서 메시지 기반 통신을 간편하게 사용할 수 있도록 도와줍니다.

 

 

 

 

 

2. ObservableRecipient 개요

더보기

✔️ 작동 방식

 

구성 
요소설명
Messenger WeakReferenceMessenger.Default로 메시지를 보내고 받음
IsActive true일 때만 메시지를 수신할 수 있음 (디폴트: false)
Receive(TMessage) 메시지를 받았을 때 자동으로 실행되는 메서드
WeakReferenceMessenger.Default.RegisterAll(this) 수신자 등록 – 자동 등록도 가능하지만 명시적 호출 권장
[MainViewModel] ---> (Messenger.Send)
                         ↓
                [ObservableRecipient]
                         ↓
                  Receive(TMessage)
  • 메시지는 전역 메신저 인스턴스를 통해 전달됨
  • 수신자는 IsActive가 true여야 하고 Receive()를 구현해야 수신 가능
  • 등록은 Register 혹은 RegisterAll로 수행 가능

 

 

 


✔️
 작동 방식

  • CommunityToolkit.Mvvm.Input.RelayCommand는 ICommand 인터페이스를 자동으로 구현해주는 소스 생성기(SG) 기반 기능입니다.
  • 버튼 클릭, 이벤트 실행, 단축키 처리 등 사용자 액션을 ViewModel의 메서드로 연결해줍니다.
  • [RelayCommand] 특성을 메서드에 붙이면 자동으로 <메서드이름>Command 속성이 생성됩니다.

 

 

 

 

✔️ 왜 필요한가?

  • ViewModel 간 결합도를 낮춘 메시지 기반 통신 가능
  • ViewModel이 필요할 때만 메시지 수신 (IsActive 제어)
  • INotifyPropertyChanged 기능 내장

 

적용 구조 목적
IsActive = false → 수신 안 됨 수신 조건 실험
ViewModel 간 직접 참조 ❌ 낮은 결합도 설계 경험
Receive() 내부 로직 작성 메시지 처리 로직 설계

 

 

 

 


3. 예제1 (MainView → DetailView, LogView)

더보기

✔️ 동작 시나리오

  • MainView.xaml.cs에 WeakReferenceMessenger 등록 → View에서도 메시지 수신
  • 메시지 수신 시 MessageBox로 사용자에게 알림
  • 뷰와 ViewModel이 함께 메시지를 수신하므로 메시지 흐름을 시각적으로 학습 가능


📁 프로젝트 구조

ObservableRecipientSample/
│
├── Models/
│   └── Student.cs
│
├── Messages/
│   └── StudentSelectedMessage.cs
│
├── ViewModels/
│   ├── MainViewModel.cs           // 송신자
│   └── DetailViewModel.cs         // 수신자1
│   └── MessageLogViewModel.cs     // 수신자2
│
├── Views/
│   ├── MainView.xaml
│   └── DetailView.xaml
│   └── MessageLogView.xaml
│
└── App.xaml.cs

 

 

 

✔️  Model 클래스 만들기

 

public class Student
{
    public string Name { get; set; } = string.Empty; // 학생 이름
    public int Age { get; set; }      // 학생 나이
}

 


✔️ ViewModel 클래스 만들기 (MainViewModel.cs)

//

 

 

✔️ XAML 화면 구성

<

 

 

✔️ 결과

 

  • 항목 클릭 시 ViewModel.SelectedItem이 변경되며, 해당 항목의 IsSelected가 true가 됩니다.
  • 트리거에 의해 선택된 항목만 배경색이 변경됩니다.

 

 

✔️ 소스코드

 

WPF_ToolKit07.zip
0.14MB

 

 

 

 

 

4. 예제2  (MainView → 선택 DetailView )

더보기

✔️ 동작 시나리오

 

  • 학생 리스트 → 선택 → 상세보기 구조
  • DetailView를 Dialog로 전환
  • Messenger로 객체(Student) 전체 전달


📁 프로젝트 구조

ObservableRecipientSample/
│
├── Models/
│   └── Student.cs
│
├── Messages/
│   └── StudentSelectedMessage.cs
│
├── ViewModels/
│   ├── MainViewModel.cs           // 송신자
│   └── DetailViewModel.cs         // 수신자
│
├── Views/
│   ├── MainView.xaml
│   └── DetailView.xaml
│
└── App.xaml.cs

 

 

 

✔️  Model 클래스 만들기

 

public class Student
{
    public string Name { get; set; } = string.Empty; // 학생 이름
    public int Age { get; set; }      // 학생 나이
}

 


✔️ ViewModel 클래스 만들기 (MainViewModel.cs)

//

 

 

✔️ XAML 화면 구성

<

 

 

✔️ 결과

 

  • 항목 클릭 시 ViewModel.SelectedItem이 변경되며, 해당 항목의 IsSelected가 true가 됩니다.
  • 트리거에 의해 선택된 항목만 배경색이 변경됩니다.

 

 

✔️ 소스코드

 

WPF_ToolKit07_02.zip
0.11MB

 

 

 

 

 

5. 예제3 - (MainView → 선택  DetailView  //  LogView)

더보기

✔️ 추가 구현 기능


기능
설명
ViewModel 간 양방향 메시지 전달 Main → Detail 
Main → Log 
선택된 창(Target)에만 메시지 전달 TargetView 문자열로 분기 처리 (DetailView, LogView)
DI 확장 구조 준비 모든 View에서 ViewModel 바인딩 → 추후 DI 컨테이너로 대체 가능 (예: App.xaml.cs에서 IServiceProvider 등록)
타이밍 보장 창 생성 후 Loaded 시점에 메시지 전송

 

📁 프로젝트 구조

ObservableRecipientSample/
│
├── Models/
│   └── Student.cs
│
├── Messages/
│   └── StudentSelectedMessage.cs
│
├── ViewModels/
│   ├── MainViewModel.cs           // 송신자
│   └── DetailViewModel.cs         // 수신자1
│   └── LogViewModel.cs            // 수신자2
│
├── Views/
│   ├── MainView.xaml
│   └── DetailView.xaml
│   └── LogView.xaml
│
└── App.xaml.cs

 

 

 

✔️  Model 클래스 만들기

 

public class Student
{
    public string Name { get; set; } = string.Empty; // 학생 이름
    public int Age { get; set; }      // 학생 나이
}

 


✔️ ViewModel 클래스 만들기 (MainViewModel.cs)

//

 

 

✔️ XAML 화면 구성

<

 

 

✔️ 결과

 

  • 항목 클릭 시 ViewModel.SelectedItem이 변경되며, 해당 항목의 IsSelected가 true가 됩니다.
  • 트리거에 의해 선택된 항목만 배경색이 변경됩니다.

 

 

✔️ 소스코드

 

WPF_ToolKit07_03.zip
0.11MB

 

 

 

 

6. 예제4 - (MainView → 선택  DetailView)

더보기
  • MessengerReply 구현 예제 (양방향 요청/응답 구조)

 

WPF_ToolKit07_04.zip
0.17MB

 

 

7. 예제5 - DependencyInjection

 

더보기


추가 확장

  • Prism, Autofac 또는 Microsoft.Extensions.DependencyInjection으로 DI 완성
  • 창 재사용 구조 (싱글턴 View or ViewModel 보관소)