【问题标题】:WPF repaint issueWPF 重绘问题
【发布时间】:2011-05-11 10:36:11
【问题描述】:

我在重绘我的 WPF 控件时遇到问题。

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

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

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

有人知道这个问题吗?

【问题讨论】:

  • 我不确定这是否可行,但您可以通过挂钩到 Windows 窗体 OnPaint 事件来强制 WPF 重新绘制自身吗?我不确定这将如何通过互操作进行,但值得一试! msdn.microsoft.com/en-us/library/…
  • 不要覆盖 OnPaint,宿主控件已经有一个正常工作的 OnPaint,它只需要被告知重绘自己,例如通过调用 Invalidate() - 请参阅下面的帖子了解更多信息。

标签: wpf wpf-controls winforms-interop


【解决方案1】:

不久前,MSDN 杂志提供了此问题的解决方案。它展示了如何使您的 WPF 应用程序“具有电源意识”,即响应电源通知。这是一篇了不起的文章,也是“必读”。

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

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

使用的技术:

  • WPF
  • .Net Framework 3.0
  • Windows Vista / Windows XP

【讨论】:

  • 我刚刚浏览了这篇文章。我不确定这篇文章是否解决了如何让窗口刷新,只是如何编写一个将被调用的函数(您应该在其中插入刷新代码)。
【解决方案2】:

通常,在 Windows 窗体中,对 Control 调用 .Invalidate() 会导致它重新绘制自身(通过将整个控件的验证矩形设置为“脏”,然后让它异步调用自己的绘制事件。——如果你只是调用 winforms 中的 Paint 方法 首先使无效,您将只能重绘之前标记为脏的部分——因为 windows 使用Dirty Rectangles approach 来节省重绘时间。) p>

希望您可以在 WPF 主机控件上调用 .Invalidate() 或仅在表单本身上调用 .Invalidate()(例如“this.Invalidate();”)

在您的表单上启用双缓冲也可能会有所帮助,但我不确定这一点 - 不过值得尝试。

@Hasan 上面给了你部分答案——如何连接到 Windows 消息泵并接收 Windows 电源事件通知——但它本身不会导致你的窗口被重新粉刷(至少据我所知) ) -- 它更像是一个通知,上面写着“嘿,你即将遇到你讨厌的那个问题。真糟糕。”

所以这可能就像挂钩到 Hasan 的消息泵内容然后调用“this.Invalidate();”一样简单任何时候收到电源事件通知。虽然这种解决方案可能有点矫枉过正。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-05
    • 2013-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多