我尝试在后台执行某些任务时打开材料设计对话框。因此,我用DialogHost <materialDesign:DialogHost>
包装了DockPanel,并用回调委托重载了Show
方法。
当我单击一个按钮时,应该显示任务执行过程中的进度对话框,例如
private async void LoadConfigButton_Click(object sender, RoutedEventArgs e)
{
var dialogContent = new TextBlock
{
Text = "Loading.... Please wait.",
Margin = new Thickness(20)
};
await DialogHost.Show(dialogContent,
new DialogOpenedEventHandler((object senderDialog, DialogOpenedEventArgs args) =>
{
// DoStuffMethod();
}));
}
现在,我看到进度对话框,但是仅在"Do stuff method"
完成之后。
我在这里想念什么?
答案 0 :(得分:1)
没有迹象表明您的
// DoStuffMethod();
也是异步方法。如果不是,请让Dispatcher异步执行工作以防止阻塞
I.E。
App.Current.Dispatcher.Invoke(async () => DoStuffMethod());
我只是在Google上进行了搜索,但还记得该调度程序对象应该具有一个您也可以调用的InvokeAsync()方法。
您可以如上所述访问调度程序,但是您的控件还应该具有可用的Dispatcher属性,可以以相同的方式使用该属性。
答案 1 :(得分:1)
调用DialogHost.Show时,DialogOpenedEventHandler is invoked synchronously。
如果DoStuffMethod被阻止,它将阻止对话框显示直到完成。如果要在之后调用 对话框,则有两个选择。
将调用包装在Task.Run内部。假定它是一个无效的返回方法。如果不是,则可能需要查看另一个overloads中的一个。请注意,这将导致该方法在后台线程上运行。如果方法中需要触摸UI元素的任何内容,您将需要利用Dispatcher。Invoke / BeginInvoke,就像其他人提到的那样。
Task.Run(DoStuffMethod);
使方法在UI的调度程序上排队。当您使用Dispather.BeginInvoke时,该方法将排队在当前调度程序队列中。这不是静态方法,因此您将需要获取Dispatcher的实例(如果您正在执行MVVM,并且此代码在视图模型中,则可能会出现问题)。通常,您可以直接在UI元素上使用Dispatcher属性,也可以使用静态属性Application.Current.Dispatcher访问一个。
var dispatcher = ...
dispatcher.BeginInvoke(DoStuffMethod);