在对话框视图模型中取消打开对话框 [英] Cancel opening dialog in dialog view model

查看:72
本文介绍了在对话框视图模型中取消打开对话框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Prism 7.2.0.我想知道是否可以取消视图模型中的打开对话框,如果参数无效,它会实现 IDialogAware .我尝试了以下代码,但它不起作用.

I use Prism 7.2.0. I wonder if it is possible to cancel opening dialog in a view model, which implements IDialogAware in case of invalid parameters. I tried the following code but it does not work.

If parameters Is Nothing Then
    'No parameters, close
    Me._SysDlg.ShowMessageBox("Invalid parameters for Visit window (no prameters).", MessageBoxButton.OK, MessageBoxImage.Error)
    RaiseEvent RequestClose(New DialogResult(ButtonResult.Cancel))
Else
' ...

推荐答案

您无法取消在对话框视图模型本身中打开对话框.这是因为 DialogService 的实现方式.来自 来源 您可以看到,OnDialogOpened(IDialogParameters parameters) 方法在显示对话框之前 被调用,并且中间没有任何检查来阻止它.尽管如此,还是有一些选择可以达到预期的结果.

You cannot cancel opening the dialog in the dialog view model itself. That is because of the way that the DialogService is implemented. From the source you can see, that the OnDialogOpened(IDialogParameters parameters) method is called before the dialog itself is shown and there are no checks in between to prevent it. Nevertheless, there are options to achive the desired result.

  1. 在调用对话服务以显示对话之前检查对话参数的有效性
  2. 创建您自己的对话服务实现

我推荐使用第一种方法,因为它需要更少的努力,并且在传递数据之前检查数据的有效性更合理.我认为调用一个验证其参数并再次关闭的对话框没有意义.

I recommend to use the first approach, because it requires less effort and it is more reasonable to check the validity of your data before passing it. I do not think taht it makes sense to call up a dialog that validates its parameters and closes itself again.

我对 Visual Basic 不熟悉,所以我只能提供一个使用 C# 的例子.然而,想法是一样的.

I am not familiar with Visual Basic, so I can only provide an example using C#. However, the idea is the same.

  1. 创建用于验证对话框参数的接口.

public interface IDialogParametersValidator
{
   bool ValidateDialogParameters(IDialogParameters parameters);
}

  1. 为您的扩展对话服务创建一个接口.

public interface IExtendedDialogService
{
   void Show(string name, IDialogParameters parameters, Action<IDialogResult> callback, bool validateDialogParameters = false);
   void ShowDialog(string name, IDialogParameters parameters, Action<IDialogResult> callback, bool validateDialogParameters = false);
}

  1. 复制您在自定义对话服务中需要的这个对话窗口扩展类,以获取视图模型.它是 Prism 源代码中的internal,因此您需要复制一份.
  1. Copy this dialog window extensions class that you need in your custom dialog service for getting the view model. It is internal in the Prism source, so you need to make a copy.

public static class IDialogWindowExtensions
{
   public static IDialogAware GetDialogViewModel(this IDialogWindow dialogWindow)
   {
      return (IDialogAware)dialogWindow.DataContext;
   }
}

  1. 创建扩展对话服务,实现 IExtendedDialogServiceIDialogService 以实现兼容性.您可以从 Prism 复制 DialogService 并为验证做一些小的调整.首先,您需要在 ShowDialogInternal 方法中添加一个参数 validateDialogParameters.然后添加一个检查,检查是否应验证对话参数,以及如果我们必须这样做,对话参数是否有效.AreDialogParametersValid 方法将查找实现 IDialogParametersValidator 接口的视图模型,并用它验证对话框参数.如果对话框参数无效,ShowDialogInternal 将直接返回而不显示对话框.最后,您需要实现 ShowShowDialog 方法,它们只需使用适当的参数调用 ShowDialogInternal 方法.
  1. Create the extended dialog service, that implements IExtendedDialogService as well as IDialogService for compatibility. You can copy the DialogService from Prism and make small adjustments for the validation. First, you need to add a parameter validateDialogParameters to the ShowDialogInternal method. Then you add a check if the dialog parameters shall be validated and if the dialog parameters are valid if we have to do so. The method AreDialogParametersValid will look for view models that implement the IDialogParametersValidator interface and validates the dialog parameters with it. If the dialog parameters are invalid, ShowDialogInternal will just return without showing the dialog. Finally, you need to implement the Show and ShowDialog methods, which simply call the ShowDialogInternal method with appropriate parameters.

public class ExtendedDialogService : IDialogService, IExtendedDialogService
{
   public void Show(string name, IDialogParameters parameters, Action<IDialogResult> callback)
   {
      ShowDialogInternal(name, parameters, callback, false);
   }

   public void ShowDialog(string name, IDialogParameters parameters, Action<IDialogResult> callback)
   {
      ShowDialogInternal(name, parameters, callback, false);
   }

   public void Show(string name, IDialogParameters parameters, Action<IDialogResult> callback, bool validateDialogParameters = false)
   {
      ShowDialogInternal(name, parameters, callback, false, validateDialogParameters);
   }

   public void ShowDialog(string name, IDialogParameters parameters, Action<IDialogResult> callback, bool validateDialogParameters = false)
   {
      ShowDialogInternal(name, parameters, callback, true, validateDialogParameters);
   }

   void ShowDialogInternal(string name, IDialogParameters parameters, Action<IDialogResult> callback, bool isModal, bool validateDialogParameters = false)
   {
      IDialogWindow dialogWindow = CreateDialogWindow();
      ConfigureDialogWindowEvents(dialogWindow, callback);
      ConfigureDialogWindowContent(name, dialogWindow, parameters);

      // This is the only change to this method, validate and cancel if necessary
      if (validateDialogParameters && !AreDialogParametersValid(dialogWindow, parameters))
         return;

      if (isModal)
         dialogWindow.ShowDialog();
      else
         dialogWindow.Show();
   }

   private static bool AreDialogParametersValid(IDialogWindow dialogWindow, IDialogParameters parameters)
   {
      if (dialogWindow.GetDialogViewModel() is IDialogParametersValidator validator)
         return validator.ValidateDialogParameters(parameters);

      return true;
   }

   // ...copy all other code from the Prism implementation of dialog service.
}

  1. 注册扩展对话服务并覆盖默认服务.

containerRegistry.RegisterSingleton<IDialogService, ExtendedDialogService>();
containerRegistry.RegisterSingleton<IExtendedDialogService, ExtendedDialogService>();

  1. 在对话框视图模型中实现 IDialogParametersValidator 接口并进行验证.
  1. Implement the IDialogParametersValidator interface in your dialog view model and validate.

public class DialogViewModel : BindableBase, IDialogAware, IDialogParametersValidator
{
   // ...your dialog view model implementation.

   public bool ValidateDialogParameters(IDialogParameters parameters)
   {
      return /* ...your validation logic here. */;
   }
}

  1. 使用新的对话服务.瞧.

dialogService.ShowDialog(nameof(YourDialog), dialogParameters, resultDelegate, true);

这篇关于在对话框视图模型中取消打开对话框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆