2011-08-22 46 views
2

我有一个强大的命名组件。ShowDialog无阻塞来电

这个问题之前已经被问过......但只是有点不同而且目的不同。

我有一个Form基类。当实现类在基类IsBusy上设置属性时。我想阻止与表单的所有交互(设置Enabled = false是不够的 - 我也想阻止移动,调整大小,关闭等......并且我不希望我的控件在IsBusy == true时看起来被禁用),并显示前面的弹出式加载表单(带有加载动画的透明无边框形式)。

在我的加载动画表单上调用ShowDialog在阻止调用窗体上的交互方面做了窍门......但显然我还希望调用表单代码继续执行。

现在我正在使用新的LoadingForm().show(),然后在我的调用窗体上处理WndProc,并且如果IsBusy == true我禁止所有WndProc消息......但我不喜欢这种方法。它可以防止表单重新绘制,我不想要。

如果我知道所有不同类型的消息让我们通过允许正确的重新绘制,我不会介意WndProc的方法,但我不知道。

所以,我的问题是:

有没有更好的解决方案?

罐有人告诉什么WndProc的消息我应该让过?或者在哪里可以找到词汇表?

谢谢。

+0

“显然我还希望调用窗体线程继续执行” - 只是不做任何事情,它会。看起来你正在解决一个不存在的问题。 –

+1

执行此操作的一种方法是启动一个新的线程以运行该操作(而不是原始的UI线程),并且完成该线程关闭“忙碌”对话框(通过调用),以便消息泵将控制恢复为原始形成。一个标准的封装是使用BackgroundWorker。 –

+0

你是对的,使用BackgroundWorder可以消除这个问题。但我想集中进行这种更改......并且我知道有些地方不使用BackgroundWorker,这会在这种更改后使这些地方无法正常工作。 – Jeff

回答

12

我结束了BeginInvoke'ing一个ShowDialog的:

myForm.BeginInvoke(new Action(() => new LoadingForm().ShowDialog())); 

有让代码后,该行继续运行,仍要堵塞与myForm的所有交互的预期效果。

+0

我想这就是大家都想告诉你的...... –

+1

我不这么认为。没有人将此作为潜在的解决方案。差远了。 – Jeff

+1

沟通总是最难的部分... –

3

如果您想通过绘画,请允许WM_PAINTWM_NCPAINT

+0

是否有一个包含所有命名消息值或静态类的静态类?还是有一个良好的词汇与int值提供? – Jeff

+1

pinvoke.net可以满足您的所有pinvoking需求:http://pinvoke.net/default.aspx/Enums/WindowsMessages.html – Blindy

2

你让它太复杂了。你所要做的就是防止对话框关闭。实现FormClosing事件(或覆盖OnFormClosing,更好),并在操作繁忙时设置e.Cancel = true。那么用户无法干扰您的流程。

这是假设您使用工作线程来执行操作。

+0

我不认为你已经正确地理解了这个问题。我不想依赖每个继承的表单,只能从后台线程安全地设置IsBusy = true。这不仅仅是我想要阻止的关闭,而是所有的互动。 – Jeff

+1

在这种情况下,您将不得不举出一个可能的交互示例。没有我能想到的。 –

+0

好吧,所以加载窗口作为对话框的唯一方法是如果我打电话给ShowDialog,对吧?如果我这样做,它会阻止调用线程。所以,设置myForm.IsBusy = true的人将会挂在那条线上,永远不会有机会将IsBusy设置回false ....所以加载表单将永远保持。我在这里误解了什么吗? – Jeff