使用 AvalonDock 2.0 时未处理的“System.ComponentModel.Win32Exception”

Posted

技术标签:

【中文标题】使用 AvalonDock 2.0 时未处理的“System.ComponentModel.Win32Exception”【英文标题】:Unhandled 'System.ComponentModel.Win32Exception' when using AvalonDock 2.0 【发布时间】:2016-10-16 12:57:07 【问题描述】:

我正在使用AvalonDock 2.0,当我打开一个停靠容器时,在调试模式下应用程序崩溃(在没有调试的情况下运行正常)。我得到以下异常:

“System.ComponentModel.Win32Exception”类型的未处理异常 发生在 WindowsBase.dll 中

附加信息:操作成功完成

我遇到了这个answer,它建议取消选中异常设置中的复选框。有线的事情是它第一次使用它就起作用了。但它不再。我在其他机器上试过,它也不起作用。有关如何解决此问题的任何建议。 Avalon 代码(第 5 行抛出异常)

protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
            if (msg == Win32Helper.WM_WINDOWPOSCHANGING) 
                if (_internalHost_ContentRendered) 
                    // the below line throw the exception
                    Win32Helper.SetWindowPos(_internalHwndSource.Handle, Win32Helper.HWND_TOP, 0, 0, 0, 0, Win32Helper.SetWindowPosFlags.IgnoreMove | Win32Helper.SetWindowPosFlags.IgnoreResize);
                
            
            return base.WndProc(hwnd, msg, wParam, lParam, ref handled);
        

【问题讨论】:

这只是库设计者的愚蠢编码。他们抛出一个 Win32Exception 错误代码,表明成功,可能是ERROR_SUCCESS。异常构造函数将该错误代码转换为消息,即“操作成功完成”——即没有发生错误。向库的维护者提交错误报告。 @CodyGray 是的,没错,但是有没有办法停止从应用程序端捕获异常。根据我在问题中引用的答案。该解决方案起初有效,但不再有效。我不知道为什么。 您在此处发布的异常消息并不表明这是第一次机会异常。无论如何,这也不太可能解决问题。它需要在库代码中的某个地方有一个 catch 块来捕获异常并处理它。我不确定您如何处理指示成功的异常。 @CodyGray 似乎他们没有在任何地方使用 catch 块,我下载了源代码并在我的机器上运行它,这给出了与我得到的完全相同的错误。我已经更新了我的问题以显示发生异常的代码。 -不知道会不会有帮助- 我假设您运行的是 64 位版本的 Windows?这可以解释为什么异常在窗口过程中被抛出时会被默默吞下。这个库中的设计决策越来越糟糕。我什至无法弄清楚为什么那条线会抛出。唯一有意义的是,他们错误地注释了 SetWindowPos 的 P/Invoke 签名,并将 PreserveSig 设置为 false。这导致指示成功的返回值与指示失败的返回值混淆。我有没有提到你应该向库的维护者提交错误报告? 【参考方案1】:

显然有一个issue 已提交,但直到现在都没有回复。

因此,作为一种解决方法,我使用来自App.xaml.cs 的Application.DispatcherUnhandledException 处理了所有未处理的异常。 请查看此answer 了解更多详情。 代码:

protected override void OnStartup(StartupEventArgs e) 
     base.OnStartup(e);
     this.DispatcherUnhandledException += AppGlobalDispatcherUnhandledException;


private void AppGlobalDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) 
     e.Handled = true;

【讨论】:

在 Windows 10 上以调试或发布模式在 VS2015 中运行时,应用此解决方案时应用程序不会在关机时终止。需要单击调试停止按钮才能最终终止应用程序。有什么想法吗?【参考方案2】:

对于登陆此页面的其他人,我可以通过关闭以下设置来解决问题:

工具 > 选项 > 调试 > 常规 > 为 XAML 启用 UI 调试工具

【讨论】:

【参考方案3】:

我的快速破解是我在调试配置期间禁用了 LayoutAutoHideWindowControl 类中的 UpdateWindowPos()。

    internal void Show(LayoutAnchorControl anchor)
    
        if (_model != null)
            throw new InvalidOperationException();

        _anchor = anchor;
        _model = anchor.Model as LayoutAnchorable;
        _side = (anchor.Model.Parent.Parent as LayoutAnchorSide).Side;
        _manager = _model.Root.Manager;
        CreateInternalGrid();

        _model.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(_model_PropertyChanged);

        Visibility = System.Windows.Visibility.Visible;
        InvalidateMeasure();
#if !DEBUG
        UpdateWindowPos();
#endif
        Trace.WriteLine("LayoutAutoHideWindowControl.Show()");
    

根据我目前的经验,这只会导致无法拖放最小化的可停靠容器。

【讨论】:

或只是#if !DEBUG(并省略#ELSE

以上是关于使用 AvalonDock 2.0 时未处理的“System.ComponentModel.Win32Exception”的主要内容,如果未能解决你的问题,请参考以下文章

AvalonDock 文档菜单下拉主题颜色 [重复]

展示如何在 MVVM 应用程序中使用 Avalondock 的示例代码 [关闭]

WPF Avalondock 将布局保存到下一次启动

发布时未调用具有 Telerik Kendo Grid Read 方法 ([DataSourceRequest]) 的 ASP.NET Core 2.0

如何使用AvalonDock将XAML文件中的LayoutAnchorableItem的Style属性绑定?

Avalondock 第二步 创建文档面板