wpf - 在 WinForms MDI 应用程序中托管 WPF 用户控件时如何避免视觉伪影?

标签 wpf mdi winforms-interop visual-artifacts

在 WinForms MDI 应用程序中托管 WPF 用户控件时,当您有多个相互重叠的表单时,会出现绘图问题,从而导致非常明显的视觉效果。将一个子窗体拖动到另一个也托管 WPF 内容的子窗体上,或者在拖动子窗体时允许主 MDI 父窗体剪裁子窗体的边缘后,这些工件大多可见。子窗体的拖放完成后,工件通常会保留在周围,但我发现将焦点设置到不同的应用程序窗口,然后重新聚焦到我的应用程序窗口,它被重新绘制,一切都很好,直到子窗体表格再次移动。请参阅下图,该图演示了该问题。

Screenshot of described artifacts

微软的人坚持认为 WinForms MDI 已经是 MDI 的充分解决方案,不需要在 WPF 中重新发明,尽管我很难相信他们尝试以这种方式创建 WPF 应用程序,因为存在明显的缺点。

更新:我遗漏的一些额外注意事项是,如果我创建这些表单而不设置 MdiParent,它们将被创建为常规表单,并且不会发生此问题。此问题似乎是 WinForms MDI 场景所特有的。另外,我目前在 Windows 7 Enterprise 上运行,我知道 Windows XP 上的结果可能有很大不同,但我无法对此进行测试。

更新:我发现了一些关于此问题的其他相关资源,我认为我应该分享这些资源。

最佳答案

另一种解决方法似乎是恢复到软件渲染,而不是利用硬件加速。这是 suggestion by Marco Zhou在 MSDN 论坛上。

public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();
        this.Loaded += delegate
        {
            var source = PresentationSource.FromVisual(this);
            var hwndTarget = source.CompositionTarget as HwndTarget;
            if (hwndTarget != null)
            {
                hwndTarget.RenderMode = RenderMode.SoftwareOnly;
            }
        };
    }
}

我已经对此进行了测试,该解决方案似乎工作得很好,到目前为止,这是我在 FoxPro 互操作场景中找到的解决此问题的唯一解决方案,该方案与我最初发布的 WinForms 场景非常相似。目前,我计划在 WinForms 项目的 MDI Parent 解决方案上使用原始的 Refresh,但对于其他 native 互操作应用程序(例如当我的 WPF 控件托管在 Visual FoxPro 中时),我将使用此解决方案。当然,除非针对这两种情况找到更优雅的解决方案。

还需要注意的是,据我所知,软件渲染是 XP 系统上的唯一选择,通常 Visual FoxPro 或 WinForms 通常会利用与 Vista 操作系统及更高版本上的 native WPF 应用程序相同类型的硬件加速。因此,当您必须处理互操作时,使用此选项可能并不像听起来那么糟糕。目前,我不知道使用此解决方案时是否有任何相关副作用,但如果有任何副作用,则必须认真考虑。

关于wpf - 在 WinForms MDI 应用程序中托管 WPF 用户控件时如何避免视觉伪影?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2589948/

相关文章:

wpf - 半透明自定义布局面板

展开时未显示 WPF 展开器验证错误

python - PyQt 和 MDI 如何正确使用?

c# - 所选文本未显示在 WPF 窗口中的 Windows 窗体 RichTextBox 控件中

c# - 如何在例程中使用 MVVM 更新 UI 中的属性

c# - 通过 xmlns 引用访问另一个项目

vb.net - 可以设置MDI子透明度吗? VB网

c++ - 在 MDI 应用程序中的不同功能区之间切换

c# - 从窗口获取线程ID

winforms - 是否对 .exe 和 Windows 窗体应用程序中的窗体使用相同的图标而不重复?