Prism 取消在对话框视图模型中打开对话框

Prism 取消在对话框视图模型中打开对话框,prism,Prism,我用。我想知道是否可以取消在视图模型中打开对话框,该模型在参数无效的情况下实现IDialogAware。我尝试了以下代码,但不起作用 如果参数为空,则 '无参数,关闭 Me.\u SysDlg.showmessagebox访问窗口参数无效,无参数,MessageBoxButton.OK,MessageBoxImage.Error RaiseEvent RequestCloseNew DialogResultButtonResult.取消 其他的 ' ... 不能取消在对话框视图模型本身中打开对话

我用。我想知道是否可以取消在视图模型中打开对话框,该模型在参数无效的情况下实现IDialogAware。我尝试了以下代码,但不起作用

如果参数为空,则 '无参数,关闭 Me.\u SysDlg.showmessagebox访问窗口参数无效,无参数,MessageBoxButton.OK,MessageBoxImage.Error RaiseEvent RequestCloseNew DialogResultButtonResult.取消 其他的 ' ...
不能取消在对话框视图模型本身中打开对话框。这是因为DialogService的实现方式。从中可以看到,OnDialogPeneDiDialogParameters方法是在显示对话框之前调用的,其间没有任何检查来阻止它。尽管如此,还是有办法达到预期的结果

在调用对话框服务以显示对话框之前,请检查对话框参数的有效性 创建自己的对话服务实现 我建议使用第一种方法,因为它需要更少的努力,而且在传递数据之前检查数据的有效性更为合理。我认为调用一个对话框来验证它的参数并再次关闭它是没有意义的

创建自己的对话服务 我不熟悉VisualBasic,所以我只能提供一个使用C的示例。不过,想法是一样的

创建用于验证对话框参数的接口。 为扩展对话框服务创建一个接口。 创建扩展对话服务,该服务实现IExtendedDialogService以及IDialogService以实现兼容性。您可以从Prism复制DialogService,并对验证进行小的调整。首先,需要向ShowDialogInternal方法添加参数validateDialogParameters。然后添加一个检查,检查对话框参数是否有效,以及如果必须这样做,对话框参数是否有效。方法AreDialogParametersValid将查找实现IDialogParametersValidator接口的视图模型,并使用它验证对话框参数。如果对话框参数无效,ShowDialogInternal将只返回而不显示对话框。最后,您需要实现Show和ShowDialog方法,它们只需使用适当的参数调用ShowDialogInternal方法。 使用新的对话框服务。瞧。
我没有足够的声誉来添加评论。 那个家伙的解决方案很好,但我对内存优化做了一些修改

我已经切换了ConfigureDialogWindowContent和ConfigureDialogWindowEvents方法,因为我不想注册这些事件

检查本身我已经移动到ConfigureDialogWindowContent方法。如果未通过,则返回按钮result.Abort

我的验证接口名为IDialogAwareEx,但可以从该文章中更改为IDialogParametersValidator

 void ShowDialogInternal(string name, IDialogParameters parameters, Action<IDialogResult> callback, bool isModal, string windowName = null)
    {
        IDialogWindow dialogWindow = CreateDialogWindow(windowName);
        if (!ConfigureDialogWindowContent(name, dialogWindow, parameters))
        {
            callback?.Invoke(new DialogResult(ButtonResult.Abort));
            return;
        }
        ConfigureDialogWindowEvents(dialogWindow, callback);

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

    }

 protected virtual bool ConfigureDialogWindowContent(string dialogName, IDialogWindow window, IDialogParameters parameters)
    {
        var content = _containerExtension.Resolve<object>(dialogName);

        var dialogContent = content as FrameworkElement;
        if (dialogContent == null)
            throw new NullReferenceException("A dialog's content must be a FrameworkElement");

        if (dialogContent.DataContext is IDialogAwareEx dialogAwareEx
            && !dialogAwareEx.CanBeOpened(parameters))
        {
            // opening is not allowed
            return false;
        }

        var viewModel = dialogContent.DataContext as IDialogAware;
        /* other codes */

        return true;
    }

谢谢你抽出时间。我很感激!
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);
}
public static class IDialogWindowExtensions
{
   public static IDialogAware GetDialogViewModel(this IDialogWindow dialogWindow)
   {
      return (IDialogAware)dialogWindow.DataContext;
   }
}
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.
}
containerRegistry.RegisterSingleton<IDialogService, ExtendedDialogService>();
containerRegistry.RegisterSingleton<IExtendedDialogService, ExtendedDialogService>();
public class DialogViewModel : BindableBase, IDialogAware, IDialogParametersValidator
{
   // ...your dialog view model implementation.

   public bool ValidateDialogParameters(IDialogParameters parameters)
   {
      return /* ...your validation logic here. */;
   }
}
dialogService.ShowDialog(nameof(YourDialog), dialogParameters, resultDelegate, true);
 void ShowDialogInternal(string name, IDialogParameters parameters, Action<IDialogResult> callback, bool isModal, string windowName = null)
    {
        IDialogWindow dialogWindow = CreateDialogWindow(windowName);
        if (!ConfigureDialogWindowContent(name, dialogWindow, parameters))
        {
            callback?.Invoke(new DialogResult(ButtonResult.Abort));
            return;
        }
        ConfigureDialogWindowEvents(dialogWindow, callback);

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

    }

 protected virtual bool ConfigureDialogWindowContent(string dialogName, IDialogWindow window, IDialogParameters parameters)
    {
        var content = _containerExtension.Resolve<object>(dialogName);

        var dialogContent = content as FrameworkElement;
        if (dialogContent == null)
            throw new NullReferenceException("A dialog's content must be a FrameworkElement");

        if (dialogContent.DataContext is IDialogAwareEx dialogAwareEx
            && !dialogAwareEx.CanBeOpened(parameters))
        {
            // opening is not allowed
            return false;
        }

        var viewModel = dialogContent.DataContext as IDialogAware;
        /* other codes */

        return true;
    }