[英]C# Modal dialog box (ShowDialog or MessageBox.Show) in async method not works as expected
我有一个最顶层的 WinForm,它带有一个简单的按钮,可以异步执行一些命令:
private async void button1_Click(object sender, EventArgs e)
{
await System.Threading.Tasks.Task.Run(() =>
{
System.Threading.Thread.Sleep(2000);
//Problem1: not works as "modal" dialog box (Main form remains active!)
new Form().ShowDialog();
//Problem2: not shown as "modal" messagebox (Main form remains active!)
MessageBox.Show("Test");
});
}
在异步 function 内部是 Messagebox.Show ()和ShowDialog()方法,但是:
问题 1(已解决):新表单未作为模式对话框打开(主表单仍处于活动状态且可访问!)
问题 2(已解决): MessageBox.Show()方法不表现为模式对话框(主窗体仍处于活动状态且可访问。)。
我需要async-await以防止主 UI 冻结,但我还希望内部的消息框(和子表单)显示为模式对话框。 如何通过异步方法显示模式对话框(在最顶层的主窗体上)?
谢谢
问题一的解决方案: ShowDialogAsync扩展方法解决了问题。
问题2的解决方案:
private async void button1_Click(object sender, EventArgs e)
{
var handle = this.Handle;
await System.Threading.Tasks.Task.Run(() =>
{
System.Threading.Thread.Sleep(2000);
//Solution for Problem2:
NativeWindow win32Parent = new NativeWindow();
win32Parent.AssignHandle(handle);
//Works as expected (Topmost and Modal):
MessageBox.Show(win32Parent, "Test");
});
}
Task.Run()
在后台线程中运行工作。 通常,您不应该从后台线程中显示 windows,但您可以。 要解决您的问题,您需要使用 UI 线程 Dispatcher。
Application.Current.Dispatcher.Invoke(() => MessageBox.Show("Test"));
或者
Application.Current.Dispatcher.Invoke(() => new Form().ShowDialog());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.