在使用DockPanel与ChrominumFx时,当在以下条件下拖动窗体时,会发生ChromiumWebBrowser崩溃的情况,此种情况也会在DockPanel与GeckoFX或CefSharp结合使用时出现。

出现条件:

  1. 当Form表单初始时以DockState.Document,然后拖动此表单到非DockState.Document模式时,可以是DockState.Left、DockState.Right或其他。
  2. 当Form表单初始时以非DockState.Document时,然后拖动此表单到DockState.Document模式时

条件总结:即DockState.Document与其他模式切换时,会出现浏览器控件崩溃的情况。

出现此问题原因是DockPanel动态改变了Form表单的MdiParent,严格来说,并不是DockPanel的问题,如果直接使用Winform的MDI窗口模式,只要改变Form表单的MdiParent,也会导致浏览器控件崩溃。

为什么出现这个原因,目前并未深入分析,主要是也不知道从哪里开始分析,因为只是使用GeckoFX、ChrominumFX、CefSharp第三方浏览器控件才会出现此问题,而.NET 自带的WebBrowser没有此问题。

解决办法:

修改DockPanel部分源码,核心思路是在设置MdiParent之前,把浏览器控件从Form表单移除,设置之后,再把浏览器控件加入Form表单。

修改源码地方(修改的DockPanel版本是:2.13):

在DockContentHandler.CS类中 1053行之后,增加如下代码:

 private static readonly object MdiParentChangingEvent = new object();
/// <summary>
/// 开始设置MdiParent之前事件
/// </summary>
public event EventHandler MdiParentChanging
{
add { Events.AddHandler(MdiParentChangingEvent, value); }
remove { Events.RemoveHandler(MdiParentChangingEvent, value); }
}
protected virtual void OnMdiParentChanging(EventArgs e)
{
EventHandler handler = (EventHandler)Events[MdiParentChangingEvent];
if (handler != null)
handler(this, e);
} private static readonly object MdiParentChangedEvent = new object();
/// <summary>
/// 设置MdiParent之后的事件
/// </summary>
public event EventHandler MdiParentChanged
{
add { Events.AddHandler(MdiParentChangedEvent, value); }
remove { Events.RemoveHandler(MdiParentChangedEvent, value); }
}
protected virtual void OnMdiParentChanged(EventArgs e)
{
EventHandler handler = (EventHandler)Events[MdiParentChangedEvent];
if (handler != null)
handler(this, e);
}

修改 DockContentHandler.CS类 785行的SetPane方法

 private void SetPane(DockPane pane)
{
if (pane != null && pane.DockState == DockState.Document && DockPanel.DocumentStyle == DocumentStyle.DockingMdi)
{
if (Form.Parent is DockPane)
SetParent(null);
if (Form.MdiParent != DockPanel.ParentForm)
{
FlagClipWindow = true;
OnMdiParentChanging(EventArgs.Empty);
// The content form should inherit the font of the dock panel, not the font of
// the dock panel's parent form. However, the content form's font value should
// not be overwritten if it has been explicitly set to a non-default value.
if (PatchController.EnableFontInheritanceFix == true && Form.Font == Control.DefaultFont)
{ Form.MdiParent = DockPanel.ParentForm;
//Form.MdiParent = null;
Form.Font = DockPanel.Font;
}
else
{
Form.MdiParent = DockPanel.ParentForm;
//Form.MdiParent = null;
}
OnMdiParentChanged(EventArgs.Empty);
}
}
else
{
FlagClipWindow = true;
if (Form.MdiParent != null)
{
OnMdiParentChanging(EventArgs.Empty);
Form.MdiParent = null;
OnMdiParentChanged(EventArgs.Empty);
}
if (Form.TopLevel)
Form.TopLevel = false;
SetParent(pane);
}
}

修改DockContent.CS类,在317行以后增加:

  private static readonly object MdiParentChangingEvent = new object();
/// <summary>
/// 开始设置MdiParent之前事件
/// </summary>
public event EventHandler MdiParentChanging
{
add { Events.AddHandler(MdiParentChangingEvent, value); }
remove { Events.RemoveHandler(MdiParentChangingEvent, value); }
}
protected virtual void OnMdiParentChanging(EventArgs e)
{
EventHandler handler = (EventHandler)Events[MdiParentChangingEvent];
if (handler != null)
handler(this, e);
} private static readonly object MdiParentChangedEvent = new object();
/// <summary>
/// 设置MdiParent之后的事件
/// </summary>
public event EventHandler MdiParentChanged
{
add { Events.AddHandler(MdiParentChangedEvent, value); }
remove { Events.RemoveHandler(MdiParentChangedEvent, value); }
}
protected virtual void OnMdiParentChanged(EventArgs e)
{
EventHandler handler = (EventHandler)Events[MdiParentChangedEvent];
if (handler != null)
handler(this, e);
} private void DockHandler_MdiParentChanging(object sender, EventArgs e)
{
OnMdiParentChanging(e);
}
private void DockHandler_MdiParentChanged(object sender, EventArgs e)
{
OnMdiParentChanged(e);
}

在 DockContent.CS类 14 行以后增加:

  m_dockHandler.MdiParentChanging += new EventHandler(DockHandler_MdiParentChanging);
m_dockHandler.MdiParentChanged += new EventHandler(DockHandler_MdiParentChanged);

最后,在你的Form表单构造函数那里增加:

this.MdiParentChanging += (o, e) => {
this.Controls.Remove(this.MainWebBrowser);
};
this.MdiParentChanged += (o, e) => {
this.Controls.Add(this.MainWebBrowser);
};

至此,可解决浏览器控件崩溃问题。

DockPanel与GeckoFX、ChrominumFX、CefSharp结合使用问题的更多相关文章

  1. 关于CefSharp的坎坷之路

    项目背景: 公司的XX产品需要升级和以后支持多平台的使用.因为之前项目是由WPF实现的.目前以后想作为Html5来展示页面. 因为涉及到整体更改遇到的问题较多以及其他原因,所以只是内部内容区域先替换为 ...

  2. 在WPF中使用CefSharp嵌入浏览器

    日常开发中,我们需要将一些Web页面嵌入到桌面客户端软件中.下面我们使用CefSharp嵌入浏览器来实现. 首先先介绍一下CefSharp嵌入式浏览器,它是基于Google浏览器的一个组件,我们可以在 ...

  3. 黄聪:C#使用GeckoFx拦截监控Http数据

    找了整整两天,在大海捞针之后,终于在上古代码中找到了一个可用的.... 可以用喜极而泣来形容测试有效之后的心情!!! 跟cefsharp相比geckofx最大的优点就是模式更接近于IE,包括node. ...

  4. 【WPF】使用CefSharp嵌入HTML网页

    需求:WPF项目中要做用户的商铺主页,由于考虑到每个商家的主页布局各不相同,不能用XAML写死布局.最好的办法是WPF这边XAML写好一个容器,用户使用HTML可视化编辑器(比如这个)来准备好网页,输 ...

  5. 在WPF中使用CefSharp嵌入浏览器(转)

    在WPF中使用CefSharp嵌入浏览器   日常开发中,我们需要将一些Web页面嵌入到桌面客户端软件中.下面我们使用CefSharp嵌入浏览器来实现. 首先先介绍一下CefSharp嵌入式浏览器,它 ...

  6. Winform下CefSharp的引用、配置、实例与报错排除(源码)

    Winform下CefSharp的引用.配置.实例与报错排除 本文详细介绍了CefSharp在vs2013..net4.0环境下,创建Winfrom项目.引用CefSharp的方法,演示了winfro ...

  7. .net使用cefsharp开源库开发chrome浏览器(二)

    离上篇写介绍pc端的混合开发和为什么以cefsharp入手研究混合开发已经有好几天,一直忙,抽不出时间继续写怎么搭建cefsharp开发环境.其实没有时间是借口,一切都是懒,没有爱到深处. 今天继续写 ...

  8. CefSharp初识--把网页移到桌面

    在开发中我们可曾有过这样的需求,将某个网页嵌入到.Net应用中来,但Winform自带的web browser不怎么理想.CefSharp可以让我们在.Net应用中嵌入一个Chromium.它提供了W ...

  9. cefsharp设置默认语言

    cefsharp是不错的浏览器内核封装版本之一,默认语言是en-US,这个一直困扰着项目,项目好多处需修改,后来经多次尝试,才发现,原来设置默认语言这么简单. CefSharp.Settings se ...

随机推荐

  1. MFC中的几个虚函数

    1.PreTranslateMessage()和WindowProc() PreTranslateMessage是消息在送给TranslateMessage函数之前被调用的,通过函数名也可以猜出来.绝 ...

  2. s11.1 lsof:查看进程打开的文件

    功能说明 lsof 全名为list open files,也就是列举系统中已经被打开的文件,通过lsof命令,就可以根据文件找到对应的进程信息,也可以根据进程信息找到进程打开的文件. [语法格式] l ...

  3. 如何在CentOS7上安装Python3及对应问题

    首先一般来说安装好的CentOS是会自带python2.7,但是是没有安装python3的环境的 [root@host bin]# pwd /usr/bin [root@host bin]# ls p ...

  4. window下切换python

    自己的win10装了2.7和3.6版本的python.本不想装2.7的,但node.js的C++的编译居然用到2.X的python,没法子就装了2.7.那怎么切换呢? 为了方便使用,我在系统的path ...

  5. 2017-12-24 自定义view相关学习

    学习材料: http://blog.csdn.net/u010661782/article/details/52805870 http://blog.csdn.net/chengyingzhilian ...

  6. GIS数据下载

    WorldTile.hdf wuhan.hdf ... openstreetmap GIS空间数据库 分割存储. 检索效率有没有提高? 云地理服务:旅游,遥感数据处理,气温,地质,房价,人口,生活(商 ...

  7. 20155326 2016-2017-2《Java程序设计》课程总结

    20155326 2016-2017-2<Java程序设计>课程总结 (按顺序)每周作业链接汇总 20155326刘美岑的第一次作业:第一次写博客,写下了对java的期待 20155326 ...

  8. c# json转换成dynamic对象,然后在dynamic对象中动态获取指定字符串列表中的值

    using Newtonsoft.Json;using System;using System.Collections.Generic;using System.Linq;using System.T ...

  9. input.php

    <?php /** * */ class Input { function get($index = NULL, $xss_clean = FALSE) { if($index == NULL ...

  10. libtool 创建库的工具

    libtool 创建库的工具 1. 背景 在不同的系统中建立动态链接库的方法有很大的差别,这主要是因为每个系统对动态链接库的用法和实现并不相同,以及编译器对动态链接库支持的选项也不太一样. 对于开发人 ...