我想在触发键盘挂钩事件时调用ShowDialog()
,但我遇到了一些困难:
ShowDialog()
,但是我得到了一些令人讨厌的异常。我想我不能在任何其他线程中调用ShowDialog()
。ShowDialog()
(这是一个讨厌的黑客BTW,我宁愿不这样做)。但随后计时器在一个新线程中触发,然后我遇到了上一个子弹中解释的相同问题。有办法吗?
答案 0 :(得分:2)
问题可能在于您尝试将UI放在非UI线程中。使您的事件从另一个线程触发,并从您的UI线程调用运行ShowDialog()
的方法。
基本上,您希望将UI保留在UI线程上,并将其他任何内容移至后台线程。
查看Gekki Software了解一些细节(有数以万计的其他人 - 这恰好是我在研究档案中找到的第一个)。
答案 1 :(得分:1)
我不确定ShowDialog,但是当你在后台线程中尝试使用UI时遇到异常时,这意味着你应该使用UI调度程序。
尝试使用调用showdialog的委托调用您控制的任何UI对象的BeginInvoke方法(如果您在Windows窗体上)。
此外,请确保尝试(在此之前)在show对话框方法中将引用传递给有效的所有者。
答案 2 :(得分:0)
如果没有“讨厌的例外”,很难说出发生了什么。我认为这是因为你的线程不是STA线程,并且UI对象在实例化时抛出异常。将新线程的公寓模型设置为STA而不是MTA,看看是否有帮助。
如果你不知道区别是什么,你应该做一些阅读,例如 Multithreaded Apartments (MSDN)。
答案 3 :(得分:0)
你真的应该可以从KeyPress类型事件中显示对话框。
此外,如果您从另一个线程使用ShowDialog()
,它将不是模态的(没有父级)。它与使用Show()
相同。
答案 4 :(得分:0)
试试这个:
void MyKeyboardHookHandler(...)
{
WindowsFormsSynchronizationContext.Current.Post(state =>
{
Form f = new Form();
f.ShowDialog();
}, null);
}
答案 5 :(得分:-1)
ShowDialog()将阻止你的应用程序的线程,但这就是它应该做的事情。如果您不希望表单阻止您的应用程序,请改为调用Show()。
ShowDialog()不会“阻止操作系统”,所以不要不愿意使用它。