在 .NET 中显示模式对话框时出现小闪烁
我在 .NET Windows 窗体 应用程序中遇到了一个烦人的问题。
我有一个 MainForm (A) 和一个进度表单 (B),当我开始长时间操作时,它们会显示为模态。
当操作完成并且 B 关闭时,似乎我的应用程序后面的窗口(通常在 Skype 中出现)在几毫秒内被带到前面,然后我的应用程序正常激活。
虽然只是一点点的闪烁,但是很烦人。在这里我写了一些可以帮助找到解决方案的提示:
- 我在没有 IWin32Window 的情况下调用了 showDialog,但我添加了它但没有成功结果。
- 我使用
Close()
关闭了 B,然后尝试了Hide()
和Close()
但没有帮助。 - 执行 ShowDialog() 的代码是从 UI 线程调用的,因此它似乎不是线程问题。
I'm experiencing a annoying issue in my .NET Windows Forms application.
I have a MainForm (A) and a progress form (B) that is shown modal when I start a long operation.
When the operation finishes, and B is closed, it seems that the window that is behind my application (is occurs usually with Skype) is brought to front during few milliseconds and, then my application is activated normally.
Is only a small flickering, but annoying. Here I write some tips that could help to find the solution:
- I called showDialog without IWin32Window, but I added it without success result.
- I closed B using
Close()
, then I triedHide()
and thenClose()
but did not help. - The code that executes the ShowDialog() is invoked from the UI thread, so it don't seem to be a threading issue.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我也经历过这些同样的症状,这让我发疯。
我终于发现问题是我调用
this.Dispose()
而不是this.Close()
来关闭模式窗口我不知道为什么我调用 <首先是 code>this.Dispose() 。切换方法后,问题就消失了。
我意识到这个线程很旧,这不是你的问题的原因,我只是想帮助其他犯了与我相同错误的人。
I was experiencing these same symptoms and it was driving me crazy.
I finally discovered the problem was that i was calling
this.Dispose()
instead ofthis.Close()
to close the modal window I'm not sure why I calledthis.Dispose()
in the first place.After switching methods, the problem went away.
I realize that this thread is old and this is not the cause of your problem, i am just trying to help anyone else who made the same mistake that I did.
检查您是否不调用隐藏或关闭。避免闪烁的唯一方法是 DialogResult。
更新:
this.DialogResult = DialogResult.Ok
检查处理程序 OnFormClosing 等。它们可能包含错误的方法调用。
小技巧是明确设置所有者
正在编辑帖子的人 -
_dialog.ShowDialog(this)
的工作方式有点不同。查看反编译代码中的
owner = ((Control)owner).TopLevelControlInternal;
由某人编辑:
或者...
根据 MSDN,这些调用是相同的
Check if you DON'T call Hide or Close. The only way to avoid flickering is DialogResult.
Upd:
this.DialogResult = DialogResult.Ok
Check handlers OnFormClosing and etc. They might containt wrong method call.
The little trick is to set Owner explicitly
People who are editing the post -
_dialog.ShowDialog(this)
works a bit different.Look at
owner = ((Control) owner).TopLevelControlInternal;
in decompiled codeEdited by someone:
Or...
These calls are identical according to MSDN
不要对模态窗口调用
Close
(不会被释放,保证内存泄漏)Set
this.DialogResult = DialogResult.OK
Call
Dispose()
来自父级,切勿从您要关闭的表单记住处置表单所持有的所有组件 <
Dispose(bool)
中的 code>IContainer (Dispose(bool) 的 VS Designer 实现通常不足以避免内存泄漏)Do not call
Close
for modal window (it will not be disposed and memory leak is guaranteed)Set
this.DialogResult = DialogResult.OK
Call
Dispose()
from the parent, NEVER from the form you are closingRemember of disposing all of your components holding by the form
IContainer
inDispose(bool)
(VS Designer implementation of Dispose(bool) is usually not enough not to have memory leaks)就我而言,我在 VB.Net winform 应用程序中也面临着同样的问题,但情况略有不同。
我有一个用户控件,它使用 showdialog() 打开一个对话框,比如“dialog1”,在填充一些数据时,它会隐藏“dialog1”并再次使用“showdialog()”打开“dialog2”。
在隐藏dialog1和显示dialog2的过程中,会发生闪烁,并且会在后台显示窗口一段时间。
在尝试了这么多解决方案和解决方法之后,没有一个对我有用。我自己找到了一种可能对其他人有帮助的解决方法。
为了隐藏dialog1,我使用了Me.Hide(),解决方案是更改表单的不透明度,而不是调用Hide()方法。
在此解决方法之后,应用程序可以正常工作,没有任何闪烁问题。
PS:以上代码行位于 VB.Net 中,但足以让 .Net winform 应用程序开发人员了解解决此问题的想法。
In my case I was also facing the same issue in my VB.Net winform application but a bit different scenario.
I was having a user control which opens up a dialog using showdialog() say dialog1 and on filling some data it hides dialog1 and opens up dialog2 using showdialog() again.
In the process of hiding dialog1 and showing dialog2 flickering occurs and it shows the window at background for a moment.
After trying so many solutions and workarounds none work for me. I found one workaround myself which might help others.
To hide dialog1 I was using Me.Hide(), The solution is to change the opacity of form instead of calling Hide() method.
After this workaround the application works fine without any flickering issue.
PS: The above code lines are in VB.Net but enough for a .Net winform application developer to get the idea for fixing this issue.
好的,
听起来像
如果是这种情况,则可能有许多不同的原因。例如,您的视频驱动程序中可能存在错误,导致在某些条件下离屏合成出现延迟。
系统本身此时甚至可能正在经历阻塞 CPU 操作。这可能是由于代码关闭对话框并返回主窗体所需的时间造成的。您可能会查看在进度关闭和将 UI 控制权返回给用户之间是否正在执行任何其他操作。
系统可能只是内存受限,并且您的操作会导致大量交换到磁盘。当操作完成时,Windows 可能会收到通知,它需要从磁盘中提取先前交换的内存并将其推回 RAM,从而导致延迟。
我会运行该应用程序,除了任务管理器或资源监视器外,什么都没有加载,然后看看会发生什么。如果问题不再出现,请考虑向您的计算机添加更多 RAM 和/或忽略它。
如果这种情况仍然发生,并且您的内存使用量几乎所剩无几,那么请再次添加 RAM 或忽略。
如果这种情况仍然发生,但内存使用率较低,请检查您的代码,看看在关闭对话框和将主窗口的控制权释放给用户之间您正在做什么。
Okay,
it sounds like
If that's the case there are many different possible causes. For example, your video drivers might have a bug in them causing delays in off screen compositing under certain conditions.
The system itself might even be experiencing a blocking CPU operation at the moment. This is something that could be caused by the time it takes your code to close the dialog and go back to the main form. You might look to see if there is anything else you are doing between the time the progress closes and you return UI control back to the user.
The system might simply be memory constrained and your operation causes a huge swap to disk. When the operation completes, windows might be notified that it needs to pull previously swapped memory from disk and shove it back into RAM, causing a delay.
I'd run the app with Nothing else loaded but task manager or resource monitor and see what happens. If the problem no longer occurs, then look into adding more RAM to your machine and/or ignore it.
If it's still occuring, and your memory usage leaves nearly nothing left then, again, add RAM or ignore.
If it's still occuring but memory usage is low, investigate your code to see what you are doing between the closing of the dialog and release of control of the main window back to the user.