Prism:通过事件关闭对话框
Prism: Closing Dialog Through Event
我正在尝试构建一个带有加载动画的简单对话框,以便在任务 运行 时显示。
我使用 Prism IDialogService
和 IEventAggregator
但是,我得到一个 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
}
}
您要么想要 Subscribe
在 UI-Thread
eventAggregator.GetEvent<LoadingFinishedEvent>().Subscribe(close => CloseDialog(null), ThreadOption.UIThread);
或使用 Dispatcher
调用 RequestClose
。
Application.Current.Dispatcher.Invoke( () => RequestClose?.Invoke(dialogresult) );
或者您删除 Task.Run
并使 GetAll
实际上是异步的...
我正在尝试构建一个带有加载动画的简单对话框,以便在任务 运行 时显示。
我使用 Prism IDialogService
和 IEventAggregator
但是,我得到一个 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
}
}
您要么想要 Subscribe
在 UI-Thread
eventAggregator.GetEvent<LoadingFinishedEvent>().Subscribe(close => CloseDialog(null), ThreadOption.UIThread);
或使用 Dispatcher
调用 RequestClose
。
Application.Current.Dispatcher.Invoke( () => RequestClose?.Invoke(dialogresult) );
或者您删除 Task.Run
并使 GetAll
实际上是异步的...