Prism:通过事件关闭对话

Posted

技术标签:

【中文标题】Prism:通过事件关闭对话【英文标题】:Prism: Closing Dialog Through Event 【发布时间】:2021-11-14 04:07:48 【问题描述】:

我正在尝试构建一个带有加载动画的简单对话框,以便在任务运行时显示。 我使用棱镜IDialogServiceIEventAggregator 但是,我得到一个System.InvalidOperationException,因为带有动画的对话框会弹出,但任务完成后永远不会关闭。

异常消息是:调用线程无法访问此对象,因为另一个线程拥有它。

可以通过单击它的 X 按钮来关闭对话框,没有任何问题。

在非异步情况下,我可以根据需要打开和关闭对话框,但我无法专心做这种异步。

这是我迄今为止想出的,导致上述错误。

WarehouseViewModel.cs

加载数据并显示对话框。

        private async void LoadData()
        
            await WarehouseListLoad().ContinueWith(t =>  _eventAggregator.GetEvent<LoadingFinishedEvent>().Publish(true); );
        

        private async Task WarehouseListLoad()
        
            _dialogService.ShowDialog("LoadingDialogView");
            List<Warehouse> warehouses = await Task.Run(() =>
            
                List<Warehouse> list = _warehouseStore.GetAll();
                return list;
            );
        

LoadingDialogViewModel.cs

监听 LoadingFinishedEvent 并调用 RequestClose。


        public event Action<IDialogResult> RequestClose;

        public LoadingDialogViewModel(IEventAggregator eventAggregator)
        
            eventAggregator.GetEvent<LoadingFinishedEvent>().Subscribe(close => CloseDialog(null));
        

        protected virtual void CloseDialog(string parameter)
        
            RaiseRequestClose(new DialogResult(ButtonResult.None));
        

        public virtual void RaiseRequestClose(IDialogResult dialogResult)
        
            try
            
                RequestClose?.Invoke(dialogResult);
            
            catch(System.InvalidOperationException ex)
            
                Debug.WriteLine(ex.Message);
                //System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it
            
        

【问题讨论】:

你为什么在这里混合async/awaitContinueWith?这是为了混淆代码吗? 【参考方案1】:

您要么想在 UI 线程上Subscribe

eventAggregator.GetEvent<LoadingFinishedEvent>().Subscribe(close => CloseDialog(null), ThreadOption.UIThread);

或使用Dispatcher 调用RequestClose

Application.Current.Dispatcher.Invoke( () => RequestClose?.Invoke(dialogresult) );

或者你放弃Task.Run 并使GetAll 实际上是异步的......

【讨论】:

我不知道我是如何在documentation 中读到的。非常感谢!

以上是关于Prism:通过事件关闭对话的主要内容,如果未能解决你的问题,请参考以下文章

Prism 源码解读6-事件聚合

WPF - Prism 7.1 - 导航 - 掌握选项卡控件 - 模态/对话框窗口

WPF Prism 对话框窗口 - 绑定到 DialogWindow 的宽度和高度

覆盖对话框关闭时的QWidget事件?

如何从父关闭按钮单击事件打开的子对话框中关闭父对话框?

Jquery UI 对话框关闭事件所有可能的方式合二为一