我们在一个相当大而复杂的桌面应用程序中遇到了一些问题,其中使用Microsoft Ribbon for WPF(或与此相关的组合)会导致计算机挂起.
下面的简化代码似乎触发了许多计算机上的Windows挂起情况.有些计算机每次都会遇到这种情况,有些人永远不会体验到它.挂起将在某些计算机上使整个会话锁定(包括num lock和大写锁定),但在其他计算机上,鼠标仍会移动(num lock仍然停止运行).当计算机无响应时,远程登录和网络共享似乎仍然有效,但无法结束控制台会话.
简而言之,似乎是行为的根本原因是几件事的结合:
我们后来WS_EX_COMPOSITED只使用了几个选定的表单来解决这个问题,但我非常想了解这个问题的根本原因.
我还没有找到一种直接的方法来重现挂起,但这个最小的应用程序似乎通过做一些最大化/恢复并将鼠标悬停在功能区按钮上方来完成业务,至少在某些机器上完成.
以下代码编译为x86 .NET 4.0,针对Microsoft WPF功能区 .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 = …Run Code Online (Sandbox Code Playgroud) 在WinForms MDI应用程序中托管WPF用户控件时,如果您有多个彼此重叠的表单会导致非常不同的可视化工件,则会出现绘图问题.将一个子窗体拖动到另一个子窗体之后,这些工件主要是可见的,这些窗体也承载WPF内容,或者允许子窗体的边缘在拖动它时由主MDI父窗体剪切.在完成子窗体的拖放操作后,工件一般会保持不变,但我发现将焦点设置到不同的应用程序窗口,然后重新聚焦到我的应用程序窗口,它重新绘制,并且一切都很好,直到孩子表格再次移动.请参阅下面的图片来说明问题.

那些在微软的人坚持认为WinForms MDI已经是MDI的充分解决方案,并且不需要重新发明WPF,尽管我发现很难相信他们尝试以这种方式创建WPF应用程序,因为它有明显的缺点.
更新:我遗漏的一些额外注释是,如果我创建这些表单而不设置MdiParent,它们将被创建为常规表单,并且不会发生此问题.此问题似乎是WinForms MDI方案所特有的.此外,我目前在Windows 7企业版上运行,我知道在Windows XP上结果可能会有很大差异,但我无法对此进行测试.
更新:我在这个问题上找到了一些我认为应该分享的其他相关资源.