IDialogService - ViewModel에서 Dialog Popup

2023. 7. 18. 18:01· WPF
목차
  1. ✅ IDialogService
  2. 소스 코드
  3. 결과
  4. ✅ IDialogService - 끝

MVVM패턴으로 개발을 하면 주요 로직은 ViewModel 또는 Model에서 동작하고 View에서는 ViewModel에 Binding 된 값을 화면에 보여주기만 합니다. 그런데 이때 문제가 되는 부분이 새로운 Window, 또는 MessageBox를 Popup 할 때입니다. MVVM패턴을 유지하면서 새로운 View을 생성하고자 할 때 IDialogService를 사용합니다.

 

 


 

 

 

✅ IDialogService

 

좀 더 자세히 얘기하면 로직이 수행되는 도중에 특정 상황이 발생하면 새로운 화면을 Popup 해야 할 경우,

수행 중인 로직이 ViewModel, 또는 Model에 있다면 View를 제어할 수가 없습니다. MVVM 패턴에서 Model, ViewModel은 View를 알 수 없기 때문이죠.

이때 interface를 통해 View와 ViewModel에 징검다리를 만들고 App.xaml.cs에서 연결해 주면 ViewModel에서 MessageBox 등을 생성할 수 있게 됩니다.

 

IDialogService는 MS에서 제공하는 interface는 아니고 RelayCommand와 같이 사용자 편의에 의해 만들어 사용하는 keyword입니다. 

 

View와 ViewModel에서 같이 사용해야하므로 Solution 내 적절한 위치에 interface를 생성합니다.

 

 

 

소스 코드

 

IDialogService.cs

public interface IDialogService
{
    void ShowMessage(string message);
    bool ShowConfirmation(string message);
}

예제 프로젝트에서는 Message를 보여주는 MessageBox와 Yes or No를 결정하는 MessageBox, 두 가지를 만듭니다.

 

 

 

 

DialogService.cs

public class DialogService : IDialogService
{
    public void ShowMessage(string message)
    {
        MessageBox.Show(message);
    }

    public bool ShowConfirmation(string message)
    {
        return MessageBox.Show(message, "Confirmation", MessageBoxButton.YesNo) == MessageBoxResult.Yes;
    }
}

실제 View를 생성하는 클래스입니다.

MessageBox 외에도 새로운 View를 생성하고자 할 경우 이 클래스에서 구현하면 됩니다.

 

 

 

 

 

App.xaml.cs

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        
        IDialogService dialogService = new DialogService();
        MainViewModel viewModel = new MainViewModel(dialogService);
        MainWindow view = new MainWindow();
        view.DataContext = viewModel;
        view.Show();
    }
}

App.xaml.cs 에 OnStartup를 override 합니다.

DialogService를 생성하고 ViewModel에 인자로 넘겨줘서 View와 ViewModel 간 DialogService를 공유합니다.

View의 DataContext에 ViewModel을 등록하기 위해 View를 생성합니다.

view.Show() 코드로 View가 Popup되는데 이 상태에서 실행하면 View가 두 개가 생성됩니다.

 

 

 

 

 

 

App.xaml

<Application x:Class="DialogService_Test.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:DialogService_Test"
             StartupUri="MainWindow.xaml" <-- 삭제
             >
    <Application.Resources>
         
    </Application.Resources>
</Application>

StartupUri="MainWindow.xaml" 를 삭제합니다.

 

 

 

MainWindow.xaml

<Grid>
    <StackPanel Orientation="Vertical">
        <TextBlock Text="{Binding MessageText}" Width="300" Height="20" VerticalAlignment="Center" HorizontalAlignment="Center" Background="SkyBlue"
                   />
        <Rectangle Height="50"/>
        <Button Content="Popup ShowMessage" Command="{Binding CmdShowMessage}"/>
        <Button Content="Popup ConfirmMessage" Command="{Binding CmdConfirmMessage}"/>
    </StackPanel>
</Grid>

TextBlock 한 개와 Button이 두 개 있는 View를 만듭니다.

TextBlock의 Text와 각 버튼의 Command는 ViewModel과 Binding 되어있습니다.

 

 

 

 

 

MainViewModel.cs

public class MainViewModel : BaseViewModel
{
    private readonly IDialogService _dialogService;

    private string _message;
    public string MessageText
    {
        get => _message;
        set
        {
            _message = value;
            OnPropertyChanged(nameof(MessageText));
        }
    }

    private ICommand _cmdShowMessage;
    public RelayCommand<object> CmdShowMessage
    {
        get
        {
            _cmdShowMessage ??= new RelayCommand<object>(ShowMessage);
            return (RelayCommand<object>)_cmdShowMessage;
        }
    }

    private ICommand _cmdConfirmMessage;
    public RelayCommand<object> CmdConfirmMessage
    {
        get
        {
            _cmdConfirmMessage ??= new RelayCommand<object>(ShowConfirmation);
            return (RelayCommand<object>)_cmdConfirmMessage;
        }
    }


    public MainViewModel(IDialogService dialogService)
    {
        _dialogService = dialogService;
        MessageText = "TEST";
    }

    public void ShowMessage(object obj)
    {
        _dialogService.ShowMessage("Hello, world!");
        MessageText = "Hello, world!";
    }

    public void ShowConfirmation(object obj)
    {
        bool result = _dialogService.ShowConfirmation("Are you sure?");
        if (result)
        {
            MessageText = "Yes";
        }
        else
        {
            MessageText = "No";
        }
    }
}

ShowMessage 버튼, ConfirmMessage 버튼을 클릭하면 MessageBox가 Popup 되며 TextBlock에 이벤트 결과가 나타납니다.

 

 

 


 

 

결과

실행 결과 gif
실행 결과

 

 

Buy Me A Coffee

 

 

 

✅ IDialogService - 끝

 

  1. ✅ IDialogService
  2. 소스 코드
  3. 결과
  4. ✅ IDialogService - 끝
'WPF' 카테고리의 다른 글
  • WPF에서 Font를 포함 배포하는 방법
  • WPF - GMap
  • XAML Designer에서 실행 차단
  • RelayCommand (ICommand)의 이해
YUNYUN3915
YUNYUN3915

공지사항

  • 블로그 이전 취소

인기 글

태그

  • GIT
  • TreeViewItem
  • WindowsFormsHostingWpfControl
  • ICloneable
  • ItemsControl
  • 어트리뷰트
  • 윈도우탐색기
  • IValueConverter
  • TreeView
  • wpf 전역 스타일
  • C#
  • PasswordBox MVVM
  • OnPropertyChanged
  • itemssource
  • Git취소
  • wpf
  • WPF 흰색바
  • WPF style
  • 메세지팝업
  • DataGrid
  • Expanding Event
  • PasswordBox DataBinding
  • CS8602
  • ElementHost
  • 문자열 관리
  • wpf 폰트
  • DialogService
  • command
  • IDialogService
  • RelayCommand
hELLO · Designed By 정상우.v4.2.0
YUNYUN3915
IDialogService - ViewModel에서 Dialog Popup
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.