2011-05-11 97 views
16

我遇到了重新绘制我的WPF控件的问题。WPF重绘问题

将WPF控件添加为Windows窗体的ElementHost.Child。

当Windows 7进入powersave模式并恢复正常(通过移动鼠标或键盘上的按键),Windows窗体控件的其余部分被重新绘制,但WPF部分未重新绘制(以及Win 7背景在该区域中可见)。

On最小化和最大化应用程序,WPF部分被重新绘制。

任何人有任何关于这个问题的想法?

+0

我不知道这是可能的,但你可以强制WPF通过挂钩到窗体OnPaint事件重绘自己?我不确定这将如何通过互操作,但值得一试! http://msdn.microsoft.com/en-us/library/system.windows.forms.control.onpaint.aspx – stuartmclark 2011-06-15 14:06:30

+0

不要重写OnPaint,主机控件已经有一个运行的OnPaint,它只是需要告诉重新绘制自己,例如通过调用Invalidate() - 请参阅下面的帖子以获取更多信息。 – BrainSlugs83 2011-09-15 03:15:05

回答

1

此问题的解决方案早在MSDN杂志中提供。它展示了如何让WPF应用程序“了解功耗”,即响应电源通知。这是一篇不可思议的文章,也是“必读文章”。

检查此链接:Make Your WPF Apps Power-Aware

您可以在线浏览源代码或从这里下载:Code for PowerAware

用到的技术:

  • WPF
  • .Net框架3.0
  • Windows Vista/Windows XP
+0

我刚才浏览了文章。我不确定这篇文章解决了如何让窗口刷新,只是如何编写一个将被调用的函数(您应该在其中插入刷新代码)。 – 2011-09-15 03:18:53

0

通常,在Windows窗体中,调用控件的.Invalidate()会导致它重新绘制自己(通过将整个控件的验证矩形设置为“脏”,然后让它异步调用自己的绘画事件。 - 如果你只是援引的WinForms 画图方法,无需无效首先,你将只能重绘先前被标记为脏的部分 - 如Windows使用Dirty Rectangles approach,以节省时间重绘)

。希望你可以在你的WPF主机控件上调用.Invalidate(),或者直接调用窗体本身的.Invalidate()(例如“this.Invalidate();”)

在窗体上启用双缓冲也可能有帮助,但我不确定这一点 - 但这是值得的实验。

@Hasan上面给你的答案的一部分 - 如何挂钩到Windows消息泵,并接收窗口电源事件通知 - 但它本身不会导致你的窗口被重新绘制(至少从我可以告诉) - 这更多的是一个通知,说:“嘿,你即将有这个问题,你讨厌。糟透了就是你。”

所以这可能就像挂钩哈桑的消息泵的东西,然后调用“this.Invalidate();”任何时候收到电源事件通知。虽然这个解决方案可能有点矫枉过正。

如果这还不够,你可能不得不告诉WPF控件本身无效......它不能这样做,因为它没有这个方法。文档表明.InvalidateVisual()是等价的,但是我的经验让我相反。除了在winform级别失效之外,我无法帮助你。如果你找到答案,请发布!