Prism. Закрытие диалога, созданного с помощью IDialogService - PullRequest
1 голос
/ 08 октября 2019

Я пытаюсь использовать новый IDialogService, который обсуждался в выпуске github 1666. Новый IDialogService для WPF . Мне нравится эта новая функция, но я не могу найти решение для одного случая использования IDialogService по сравнению с InteractionRequest.

Есть кнопка, нажатие которой открывает немодальное диалоговое окно. Если пользователь нажимает ту же кнопку еще раз, пока диалог все еще открыт, диалог закрывается. Как это поведение должно быть правильно реализовано?

MainWindowViewModel

public class MainWindowViewModel : BindableBase
{
    private readonly IDialogService _dialogService;
    public DelegateCommand CustomPopupCommand { get; }

    public MainWindowViewModel(IDialogService dialogService)
    {
        _dialogService = dialogService;
        CustomPopupCommand = new DelegateCommand(OpenClosePopup);
    }

    private void OpenClosePopup()
    {
        // It looks like some additional logic should be implemented here.
        // How to save previously opened IDialogAware instance and close it if needed?
        _dialogService.Show("CustomPopupView", new DialogParameters("Title=Good Title"), result => { });
    }
}

CustomPopupViewModel

public class CustomPopupViewModel : BindableBase, IDialogAware
{
    private string _title;
    public string Title
    {
        get => _title;
        set => SetProperty(ref _title, value);
    }
    public DelegateCommand<object> CloseCommand { get; }

    public CustomPopupViewModel()
    {
        CloseCommand = new DelegateCommand<object>(CloseDialog);
    }

    public event Action<IDialogResult> RequestClose;

    public void OnDialogOpened(IDialogParameters parameters)
    {
        Title = parameters.GetValue<string>(nameof(Title));
    }

    public void OnDialogClosed()
    {
    }

    public bool CanCloseDialog()
    {
        return true;
    }

    public void RaiseRequestClose(IDialogResult dialogResult)
    {
        RequestClose?.Invoke(dialogResult);
    }

    private void CloseDialog(object button)
    {
        RaiseRequestClose(
            new DialogResult(button is ButtonResult buttonResult ? buttonResult : ButtonResult.Cancel));
    }
}

Iпонятия не имею, как это можно реализовать надлежащим образом, потому что метод IDialogService.Show () полностью отделен от знания о ViewModel и View. Конечно, кроме названия View.

1 Ответ

1 голос
/ 08 октября 2019

Вы всегда можете отправить событие через агрегатор событий, возможно, вам придется передать какой-то идентификатор в параметры диалога, чтобы закрыть правый диалог, если одновременно открыто более одного.

Но это действительно такнеуклюжий, я бы предпочел получить IDisposable из Show / ShowDialog, который закрывает диалог на Dispose.

public CustomPopupViewModel(IEventAggregator eventAggregator)
{
    eventAggregator.GetEvent<CloseDialogEvent>().Subscribe( id => { if (id == _id) CloseMe(); } );
}

public void OnDialogOpened(IDialogParameters parameters)
{
    _id = parameters.GetValue<string>("id");
}

_dialogService.Show("CustomPopupView", new DialogParameters("id=12345"), result => { });

_eventAggregator.GetEvent<CloseDialogEvent>().Publish("12345");
...