c# - Material Design Template WPF DialogHost 等到关闭并与 Prism EventAggregator 集成
问题描述
我正在尝试MessageBox
用DialogHost
来自MaterialDesign
库的替换标准 WPF,但我不知道如何等到用户从对话框中选择“确定”或“取消”。我面临的问题是因为我从使用事件聚合器调用的函数中调用对话框的显示。下面是我的代码:
private async void OnMessageRequest(MessageArgs obj)
{
MessageDialogModel = _messageDialogCreator();
MessageDialogModel.Load(obj.Message, obj.HasButtons);
var view = new SampleDialog
{
DataContext = MessageDialogModel
};
await DialogHost.Show(view, "RootDialog");
}
当我使用MessageBox
它时,它按预期工作。这是代码:
if (obj.HasButtons)
{
var result = MessageBox.Show(obj.Message, obj.Title, MessageBoxButton.OKCancel);
var submitArg = result == MessageBoxResult.OK
? MessageDialogResult.OK
: MessageDialogResult.Cancel;
_eventAggregator.GetEvent<MessageDialogResultEvent>().Publish(submitArg);
}
else
{
MessageBox.Show(obj.Message, obj.Title);
}
基本上需要的是在显示对话框后停止代码并等待用户选择和选项。我希望这是有道理的
解决方案
您需要做的就是等待DialogHost.Show
方法的结果并处理它,具体取决于您传递CommandParameter
给CloseDialogCommand
. 例如,我MessageBoxResult
对对话框中的按钮使用 as 命令参数,表示确定和取消。
<Button Content="OK"
Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"
CommandParameter="{x:Static MessageBoxResult.OK}"/>
<Button Content="Cancel"
Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"
CommandParameter="{x:Static MessageBoxResult.Cancel}"/>
然后在代码中,我等待结果并像在您提供的代码中一样处理它。
var result = (MessageBoxResult)await DialogHost.Show(msg, "RootDialog");
var submitArg = result == MessageBoxResult.OK
? MessageDialogResult.OK
: MessageDialogResult.Cancel;
_eventAggregator.GetEvent<MessageDialogResultEvent>().Publish(submitArg);
after 的代码DialogHost.Show
将在对话框关闭后执行。
从评论更新
既然您已经澄清了您需要发布事件的方法来等待,那么问题就完全不同了。
我想要发生的是停在“结果”处,显示对话框并等待答案。一旦用户选择 Ok 或 Cancel 继续使用代码。
DialogHost
故意构建为异步使用。目前还没有同步调用的方法,请看这个问题。相反,Prism 的事件聚合器没有Publish
返回 a Task
or的异步方法Task<T>
。因此,不能等待。此外,事件聚合器用于触发和忘记事件,因此根据定义,它不适合您当前显示对话框的同步方法,我不认为这是正确的方法。
如果要保留DialogHost
,请返回一个Task
from OnMessageRequest
,以便能够获得await
它。
private async Task OnMessageRequest(MessageArgs obj)
然后您可以等待显示对话框的方法,它应该按预期工作。
private async void OnOpenContractorDetailView(int? contractorId)
{
if (ContractorDetailViewModel != null && ContractorDetailViewModel.HasChanges)
{
var messageArgs = new MessageArgs { Message = "You've made changes. Are you sure you want to navigate away?", Title = "Question", HasButtons = true };
await void OnMessageRequest(messageArgs);
if (_dialogResult == MessageDialogResult.Cancel)
return;
}
ContractorDetailViewModel = _contractorDetailViewModelCreator();
await ContractorDetailViewModel.LoadAsync(LoadMenuArgs, contractorId);
}
您应该考虑通过OnMessageRequest
直接将对话结果作为返回值传递Task<MessageDialogResult>
,因为在处理异步方法时使用实例成员可能会导致数据竞争。
推荐阅读
- javascript - 在 routerLink 或浏览器后退按钮之后失去 Materialise javascript 和 jquery 功能
- google-chrome-extension - 如何运行 jQuery if($(this) 语句来发送 browser.runtime.sendMessage?
- dagger-2 - 通过 ParentComponent 绑定的 ChildComponent 不支持 Dagger 2 BindsInstance?
- flutter - 如何将图库或相机中的图像转换为二进制字符串?
- react-native - 路由组件必须是 React 组件
- asp.net-core - 验证不完整
- java - 这段代码有什么问题......?Java 套接字编程
- gallery - 如何更改 PrimeNG 的 p-galleria 中的图像大小?
- linux - 如何从我的 CSV 文件输出中删除 NONREF,以便在脚本运行时不会打印出该行?
- ios - UIScrollView 嵌套在 UIPageViewController 幻灯片中