代码之家  ›  专栏  ›  技术社区  ›  jpierson

在WinForms MDI应用程序中托管WPF用户控件时,如何避免视觉瑕疵?

  •  6
  • jpierson  · 技术社区  · 14 年前

    Screenshot of described artifacts

    我遗漏的几个额外的注意事项是,如果我创建这些表单时没有设置MDI父级,它们将被创建为常规表单,并且不会发生此问题。这个问题似乎是WinForms MDI场景所特有的。另外,我目前运行的Windows7企业版,我知道结果可能会有很大的不同,在WindowsXP上,但我还没有能够测试这个。

    更新:

    4 回复  |  直到 8 年前
        1
  •  8
  •   jpierson    14 年前

    另一个解决方法似乎是恢复到软件渲染,而不是利用硬件加速。这就是 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父级解决方案上使用我的原始刷新,但对于其他本机互操作应用程序(如WPF控件托管在visualfoxpro中时),我将使用此解决方案。当然,除非为这两种情况找到一个更优雅的解决方案。

    另外,值得注意的是,据我所知,软件渲染是XP系统上的唯一选项,通常VisualFoxPro NoreWinForms通常利用与Vista操作系统和更高版本上的本地WPF应用程序相同类型的硬件加速。因此,当您必须处理互操作时,使用此选项可能不像听起来那么糟糕。目前我还不知道在使用这个解决方案时有什么相关的副作用,但如果有任何副作用的话,那就必须认真考虑了。

        2
  •  2
  •   jpierson    14 年前

    嗯,我可能已经找到了一个解决办法,虽然这感觉有点像黑客。如果在移动子MDI窗体时调用MDI父窗体上的Refresh方法,那么所记录的工件就会消失。从视觉上看,当拖动一个窗口时,事情看起来有点紧张,但这似乎比我在最初的帖子中展示的例子更容易接受。

    private void Form1_Move(object sender, EventArgs e)
    {
        this.ParentForm.Refresh();
    
        System.Diagnostics.Debug.WriteLine(string.Format("Form Moved to: ({0},{1})", this.Left, this.Top));
    }
    

    更新() , 无效() , 我也在MDI父级和 Dispatcher.Invoke(DispatcherPriority.Render,…) InvalidateVisual() 在我托管的WPF控件上,但这些方法都不能用于调用accept 刷新()

    我意识到这可能不是最佳解决方案,因为每次子窗口移动几个像素时,我都会强制整个主应用程序窗口刷新,但就目前而言,这是我发现的唯一可行的解决方案。如果其他人对此有任何替代方案或改进,我将欣然接受你的回答。

        3
  •  2
  •   Ryan Strassburg    12 年前

    故障排除的第一步:更新视频驱动程序。很明显,我知道。

    我也有类似的问题,检查我的视频卡设置(NVidia控制面板)显示,全球设置设置非常高,导致较长的刷新间隔,可能会中止,如果花太长时间。将我的设置设置回默认值解决了大部分问题。但是我也运行哈希程序,它强烈地使用GPU,所以这很可能是我重新生成工件问题的原因,这在visualstudio中是非常罕见的,而且大部分都是丑陋的。

    我遇到的另一个故障排除步骤是禁用WPF的硬件加速,这可以在“HKEY\u CURRENT\u USER/SOFTWARE/Microsoft/Avalon.Graphics”中完成,也可以由应用程序完成,但这只是用于故障排除;永远不要在应用程序中设置这些,因为它将禁用所有WPF应用程序。我没有这个注册表设置,也没有添加它,所以我不确定它是否成功,但许多人说这解决了他们的问题。另请注意,有些应用程序有此选项可用,请尝试禁用它(如果可用)。

    另一个故障排除步骤是确保视频卡是用于渲染的适当层。任何支持DX9或更高版本的卡都应该足够了,但是还涉及到其他因素(就像我的情况一样),所以仅仅因为它在列表上并不意味着它就足够满足您的需要。

    最后,您可以使用visualprofiler(windowsdk的一部分)和其他工具来帮助更精确地确定WPF在图形功能方面缺乏性能的情况。

    呈现层级别注释和WPF性能信息--> http://msdn.microsoft.com/en-us/library/vstudio/ms742196(v=vs.90).aspx

    希望这对别人有帮助。

    --瑞安·斯特拉斯堡

        4
  •  0
  •   e_r_k_a_n e_r_t_u_r_a_l    9 年前

    this.WindowState = System.Windows.WindowState.Minimized;
    
    this.WindowState = System.Windows.WindowState.Normal;
    

    这似乎不是个好办法。不用把头撞到墙上。

    推荐文章