WPF重绘问题
我在重新绘制 WPF 控件时遇到问题。
WPF 控件作为 Windows 窗体的 ElementHost.Child 添加。
当 Windows 7 进入省电模式并恢复正常(通过移动鼠标或按下键盘上的按键)时,其余 Windows 窗体控件将被重新绘制,但 WPF 部分不会被重新绘制(并且 Win 7 背景在那个区域)。
在最小化和最大化应用程序时,WPF 部分被重新绘制。
有人对这个问题有任何想法吗?
I am having an issue with repaint of my WPF control.
The WPF control is added as an ElementHost.Child for a Windows form.
When Windows 7 goes into powersave mode and is brought back to normal (by moving the mouse or key press on keyboard), the rest of Windows form controls are repainted, however the WPF part is not repainted(and the Win 7 background is visible in that area).
On Minimize and maximise of the application, the WPF part is repainted.
Anyone has any idea about this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不久前 MSDN 杂志上提供了这个问题的解决方案。它展示了如何使 WPF 应用程序具有“电源感知”功能,即响应电源通知。这是一篇精彩的文章,也是“必读”的文章。
检查此链接:让您的 WPF 应用程序具有节能功能
您可以浏览在线源代码或从此处下载:PowerAware 代码
使用的技术:
The solution for this issue was provided in MSDN magazine a while back. It shows how you can make your WPF applications "power-aware" i.e. respond to power notifications. It's an amazing article and a "must-read".
Check this link: Make Your WPF Apps Power-Aware
You can browse the source code online or download it from here: Code for PowerAware
Technologies used:
一般来说,在 Windows 窗体中,在 Control 上调用 .Invalidate() 将导致它重新绘制自身(通过将整个控件的验证矩形设置为“脏”,然后让它异步调用自己的绘制事件。 -- 如果您只是调用 Paint winforms 中的方法没有首先无效,您将只能重绘之前标记为脏的部分 - 因为 windows 使用 脏矩形方法以节省重绘时间。)
希望您可以在 WPF 主机上调用 .Invalidate()控制或只是在表单本身上调用 .Invalidate() (例如“this.Invalidate();”)
在表单上启用双缓冲也可能有所帮助,但我对此不确定 - 值得进行实验 尽管。
上面的@Hasan给了你部分答案——如何连接到Windows消息泵并接收Windows电源事件通知——但它本身不会导致你的窗口被重新绘制(至少据我所知)——它更像是一个通知,说“嘿,你即将遇到你讨厌的问题。你真糟糕。”
所以这可能就像连接 Hasan 的消息泵东西然后调用“this.Invalidate();”一样简单每当收到电源事件通知时。尽管这个解决方案可能有点矫枉过正。
如果这还不够,您可能必须告诉 WPF 控件本身 Invalidate...但它无法执行此操作,因为它没有该方法。文档表明 .InvalidateVisual() 是等效的,但我的经验让我相信事实并非如此。除了在 winform 级别失效之外,我无法帮助你。如果您找到答案,请发布!
Generally, in windows forms calling .Invalidate() on a Control will cause it to repaint itself (via setting the entire control's validation rect to "dirty" and then letting it invoke its own paint event asynchronously. -- If you just invoke the Paint method in winforms without Invalidating first, you will only be able to redraw the portion that was previously marked as dirty -- as windows uses the Dirty Rectangles approach to save on redraw time.)
Hopefully you can either call .Invalidate() on your WPF host control or just call .Invalidate() on the form itself (e.g. "this.Invalidate();")
Enabling double buffering on your form might also help, but I am unsure of this -- it's worth the experiment though.
@Hasan above gave you part of the answer -- how to hook into the windows message pump which and receive windows power event notifications -- but by itself will not cause your window to be repainted (at least from what I can tell) -- it's more of a notification that says "hey, you're about to have that problem you hate. Sucks to be you."
So this is probably as simple as hooking into Hasan's message pump stuff and then calling "this.Invalidate();" any time a power event notification is received. Though that solution may be a little bit overkill.
If that's not enough you may have to tell the WPF control itself to Invalidate... which it can't do, because it doesn't have that method. The documentation suggests that .InvalidateVisual() is the equivalent, but my experience has lead me to believe otherwise. Other than invalidating at the winform's level, I can't help you. If you find the answer, please post it!