Открыть диалог в уже открытом диалоге MVVM - PullRequest
0 голосов
/ 09 марта 2019

Я смотрел отличное видео о создании DialogService, который позаботится об открытии диалогов в MVVM.Поскольку конструктор DialogService принимает владельца (тип окна) в качестве параметра, легко создать dialogService в MainWindow.Просто создайте View и ViewModel для MainWindow отдельно в App.xaml.cs и соедините все.Но проблема в том, как мне создать dialogService в диалоге, который открывается из MainWindow (чтобы открыть больше диалогов из этого диалога), поскольку я не могу получить экземпляр View диалога, который открывается из MainWindowViewModel.Вот метод для показа этого диалога.

private void ShowAdministrationDialog()
{
        AdministrationDialogViewModel viewModel = new AdministrationDialogViewModel(this.context);
        dialogService.ShowDialog(viewModel);
}

Ответы [ 2 ]

1 голос
/ 10 марта 2019

Код из видео не поддерживает ваш вариант использования. Диалоговая служба, кажется, одноэлементная, способная открывать только те диалоги, в которых главное окно является владельцем. Для многих обстоятельств это, вероятно, хорошо, для других, как для вас, это просто не работает.

Я создал пакет NuGet под названием MvvmDialogs, способный открывать диалоги при любых возможных обстоятельствах. Вы можете просмотреть код на GitHub. Я решил проблему, введя присоединенное свойство, которое действует как мост между представлениями и моделями представления. Таким образом, я всегда могу переходить от модели представления к ее представлению и из представления, проходящего вверх по дереву логического интерфейса, пока не достигну окна-владельца.

Это только одно решение проблемы, я уверен, что вы можете найти другое, если захотите создать свой собственный сервис диалогов. Если нет, всегда есть MvvmDialogs: D

0 голосов
/ 11 марта 2019

Можно было бы решить эту проблему, но я не уверен, что это сломает MVVM, поэтому решение FantasticFiasco, вероятно, лучше. В классе DialogService раздельный метод ShowDialog на 2 метода - PrepareDialog и ShowDialog

PrepareDialog:

public void PrepareDialog<TViewModel>(TViewModel viewModel) where TViewModel : IDialogRequestClose
    {
        // Finds a ViewType from Mappings
        Type viewType = Mappings[typeof(TViewModel)];

        // Creates a View instance
        IDialog dialog = (IDialog)Activator.CreateInstance(viewType);

        // Adds an event on dialog close request
        EventHandler<DialogCloseRequestedEventArgs> handler = null;
        handler = (sender, e) =>
        {
            // Dispatch handler
            viewModel.CloseRequested -= handler;

            // Reset owner's opacity
            dialog.Owner.Opacity = 1;

            // Returns a result if exists
            if (e.DialogResult.HasValue)
            {
                dialog.DialogResult = e.DialogResult;
            }
            else
            {
                dialog.Close();
            }
        };

        dialog.DataContext = viewModel;
        dialog.Owner = owner;
        dialog.Owner.Opacity = 0.5;

        // Adds handler for close request
        viewModel.CloseRequested += handler;

        // Initializes a dialog service in opening dialog's ViewModel if supports it
        IViewModelDialogService viewModelDialogService = viewModel as IViewModelDialogService;
        if (viewModelDialogService != null)
        {
            viewModelDialogService.DialogService = new DialogService((Window)dialog);
        }

        this.newWindow = (Window)dialog;
    }

ShowDialog:

public bool? ShowDialog()
    {
        if (this.newWindow == null)
        {
            throw new ArgumentNullException();
        }

        bool? result = this.newWindow.ShowDialog();

        this.newWindow = null;

        return result;
    }

Конечно, вам нужно добавить приватное поле newWindow (тип Window) в диалоговом классе обслуживания. Теперь это позволяет вам получить экземпляр представления в dialogService при вызове PrepareDialog, а после вызова PrepareDialog вы можете применить изменения к диалоговой службе ViewModel, а затем, в конце, вызвать ShowDialog

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...