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