ShowDialog无阻塞来电
问题描述:
我有一个强大的命名组件。ShowDialog无阻塞来电
这个问题之前已经被问过......但只是有点不同而且目的不同。
我有一个Form基类。当实现类在基类IsBusy
上设置属性时。我想阻止与表单的所有交互(设置Enabled = false是不够的 - 我也想阻止移动,调整大小,关闭等......并且我不希望我的控件在IsBusy == true
时看起来被禁用),并显示前面的弹出式加载表单(带有加载动画的透明无边框形式)。
在我的加载动画表单上调用ShowDialog在阻止调用窗体上的交互方面做了窍门......但显然我还希望调用表单代码继续执行。
现在我正在使用新的LoadingForm().show(),然后在我的调用窗体上处理WndProc,并且如果IsBusy == true
我禁止所有WndProc消息......但我不喜欢这种方法。它可以防止表单重新绘制,我不想要。
如果我知道所有不同类型的消息让我们通过允许正确的重新绘制,我不会介意WndProc的方法,但我不知道。
所以,我的问题是:
有没有更好的解决方案?
或
罐有人告诉什么WndProc的消息我应该让过?或者在哪里可以找到词汇表?
谢谢。
答
我结束了BeginInvoke'ing一个ShowDialog的:
myForm.BeginInvoke(new Action(() => new LoadingForm().ShowDialog()));
有让代码后,该行继续运行,仍要堵塞与myForm的所有交互的预期效果。
答
你让它太复杂了。你所要做的就是防止对话框关闭。实现FormClosing事件(或覆盖OnFormClosing,更好),并在操作繁忙时设置e.Cancel = true。那么用户无法干扰您的流程。
这是假设您使用工作线程来执行操作。
“显然我还希望调用窗体线程继续执行” - 只是不做任何事情,它会。看起来你正在解决一个不存在的问题。 –
执行此操作的一种方法是启动一个新的线程以运行该操作(而不是原始的UI线程),并且完成该线程关闭“忙碌”对话框(通过调用),以便消息泵将控制恢复为原始形成。一个标准的封装是使用BackgroundWorker。 –
你是对的,使用BackgroundWorder可以消除这个问题。但我想集中进行这种更改......并且我知道有些地方不使用BackgroundWorker,这会在这种更改后使这些地方无法正常工作。 – Jeff