.net – 导致Windows在此WPF功能区应用程序中挂起的原因

前端之家收集整理的这篇文章主要介绍了.net – 导致Windows在此WPF功能区应用程序中挂起的原因前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们在一个相当大而复杂的桌面应用程序中遇到了一些问题,其中使用Microsoft Ribbon for WPF(或与此相关的组合)会导致计算机挂起.

下面的简化代码似乎触发了许多计算机上的Windows挂起情况.有些计算机每次都会遇到这种情况,有些人永远不会体验到它.挂起将在某些计算机上使整个会话锁定(包括num lock和大写锁定),但在其他计算机上,鼠标仍会移动(num lock仍然停止运行).当计算机无响应时,远程登录和网络共享似乎仍然有效,但无法结束控制台会话.

简而言之,似乎是行为的根本原因是几件事的结合:

> Microsoft Ribbon for WPF
>在ElementHost中托管WPF控件的Windows窗体应用程序
>使用双缓冲Windows窗体(使用CreateParams)
>在WPF功能区上使用软件渲染

我们稍后通过仅在几个选定的表单上使用WS_EX_COMPOSITED来解决此问题,但我非常希望了解此问题的根本原因.

我还没有找到一种直接的方法来重现挂起,但这个最小的应用程序似乎完成了业务,至少在某些机器上,做了一些最大化/恢复并将鼠标悬停在功能区按钮上方.

以下代码针对Microsoft WPF Ribbon .NET 4.0库编译为x86 .NET 4.0.

using System;
using System.Windows.Forms;
using Microsoft.Windows.Controls.Ribbon;
using System.Windows.Interop;
using System.Windows.Forms.Integration;

namespace WindowsRibbonHang
{
    public class Form1 : Form
    {
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;  // Turn on WS_EX_COMPOSITED
                return cp;
            }
        }

        public Form1()
        {
            Ribbon ribbon = new Ribbon();

            RibbonTab tab = new RibbonTab { Header = "FooTab" };
            ribbon.Items.Add(tab);

            RibbonSplitButton button = new RibbonSplitButton { Label = "FooButton" };
            tab.Items.Add(button);

            ElementHost elementHost = new ElementHost
            {
                Dock = DockStyle.Fill,Child = ribbon,};

            Controls.Add(elementHost);
            Dock = DockStyle.Fill;

            ribbon.Loaded += (sender,args) => {
                HwndSource hwndSource = System.Windows.PresentationSource.FromVisual(ribbon) as HwndSource;
                HwndTarget hwndTarget = hwndSource.CompositionTarget;
                hwndTarget.RenderMode = RenderMode.SoftwareOnly;
            };
        }
    }

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}
尝试检查受影响的计算机上的图形驱动程序是否是最新的. WPF的工作方式与传统的GDI代码完全不同,因此有时不可靠的驱动程序会导致您描述的问题.
原文链接:https://www.f2er.com/windows/371637.html

猜你在找的Windows相关文章