DockPanel与GeckoFX、ChrominumFX、CefSharp结合使用问题
在使用DockPanel与ChrominumFx时,当在以下条件下拖动窗体时,会发生ChromiumWebBrowser崩溃的情况,此种情况也会在DockPanel与GeckoFX或CefSharp结合使用时出现。
出现条件:
- 当Form表单初始时以DockState.Document,然后拖动此表单到非DockState.Document模式时,可以是DockState.Left、DockState.Right或其他。
- 当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结合使用问题的更多相关文章
- 关于CefSharp的坎坷之路
项目背景: 公司的XX产品需要升级和以后支持多平台的使用.因为之前项目是由WPF实现的.目前以后想作为Html5来展示页面. 因为涉及到整体更改遇到的问题较多以及其他原因,所以只是内部内容区域先替换为 ...
- 在WPF中使用CefSharp嵌入浏览器
日常开发中,我们需要将一些Web页面嵌入到桌面客户端软件中.下面我们使用CefSharp嵌入浏览器来实现. 首先先介绍一下CefSharp嵌入式浏览器,它是基于Google浏览器的一个组件,我们可以在 ...
- 黄聪:C#使用GeckoFx拦截监控Http数据
找了整整两天,在大海捞针之后,终于在上古代码中找到了一个可用的.... 可以用喜极而泣来形容测试有效之后的心情!!! 跟cefsharp相比geckofx最大的优点就是模式更接近于IE,包括node. ...
- 【WPF】使用CefSharp嵌入HTML网页
需求:WPF项目中要做用户的商铺主页,由于考虑到每个商家的主页布局各不相同,不能用XAML写死布局.最好的办法是WPF这边XAML写好一个容器,用户使用HTML可视化编辑器(比如这个)来准备好网页,输 ...
- 在WPF中使用CefSharp嵌入浏览器(转)
在WPF中使用CefSharp嵌入浏览器 日常开发中,我们需要将一些Web页面嵌入到桌面客户端软件中.下面我们使用CefSharp嵌入浏览器来实现. 首先先介绍一下CefSharp嵌入式浏览器,它 ...
- Winform下CefSharp的引用、配置、实例与报错排除(源码)
Winform下CefSharp的引用.配置.实例与报错排除 本文详细介绍了CefSharp在vs2013..net4.0环境下,创建Winfrom项目.引用CefSharp的方法,演示了winfro ...
- .net使用cefsharp开源库开发chrome浏览器(二)
离上篇写介绍pc端的混合开发和为什么以cefsharp入手研究混合开发已经有好几天,一直忙,抽不出时间继续写怎么搭建cefsharp开发环境.其实没有时间是借口,一切都是懒,没有爱到深处. 今天继续写 ...
- CefSharp初识--把网页移到桌面
在开发中我们可曾有过这样的需求,将某个网页嵌入到.Net应用中来,但Winform自带的web browser不怎么理想.CefSharp可以让我们在.Net应用中嵌入一个Chromium.它提供了W ...
- cefsharp设置默认语言
cefsharp是不错的浏览器内核封装版本之一,默认语言是en-US,这个一直困扰着项目,项目好多处需修改,后来经多次尝试,才发现,原来设置默认语言这么简单. CefSharp.Settings se ...
随机推荐
- php $_SERVER中的一些选项说明
1, $_SERVER['SCRIPT_FILENAME'] 和 常量 __FILE__的区别(一般情况下两者的显示相同,都是显示文件的绝对路径,包括文件名,显示的起点是 电脑根目录 /) ①,如果在 ...
- mysql学习之路_事物_存储过程_备份
数据备份与还原 备份:将当前已有的数据保留. 还原:将已经保留的数据恢复到对应表中 为什么要做数据备份 1,防止数据丢失,被盗,误操作 2,保护数据记录 数据备份还原方式有多种:数据表备份 单表数据备 ...
- hadoop 组件 hdfs架构及读写流程
一 . Namenode Namenode 是整个系统的管理节点 就像一本书的目录,储存文件信息,地址,接受用户请求,等 二 . Datanode 提供真实的文件数据,存储服务 文件块(block)是 ...
- 【王者荣耀之IT大神版】铭文说明
铭文共分五级: 一级:仅有老师提供的笔记 二级:添加了自己的听课笔记 三级:添加问题+解决方案(常遇到的问题以及自己实践上遇到的问题,排位赛遇到的遗忘点) 四级:熟记铭文与并添加联想学过的知识 五级: ...
- Kafka常用命令收录
目录 目录 1 1. 前言 2 2. Broker默认端口号 2 3. 安装Kafka 2 4. 启动Kafka 2 5. 创建Topic 2 6. 列出所有Topic 3 7. 删除Topic 3 ...
- Java理论学时第二节。课后作业。
枚举不属于原始数据类型,它的每个具体值都引用一个特定的对象,相同的值则引用同一个对象. 可以使用“==”和equals()方法直接比对枚举变量的值,换句话说,对于枚举类型的变量,“==”和equals ...
- POJ3181--Dollar Dayz(动态规划)
Farmer John goes to Dollar Days at The Cow Store and discovers an unlimited number of tools on sale. ...
- html5打开摄像头并用canvas模拟拍照 - 转
<video id="video" width="640" height="480" autoplay></video&g ...
- index.jsp首页访问不了的解决方法
解决方法: Tomcat,将项目添加到里面 部署解包的webapp目录 将Web项目部署到Tomcat中的方法之一,是部署没有封装到WAR文件中的Web项目.要使用这一方法部署未打包的webapp目录 ...
- 02:OC和C对比
1.源文件对比 C语言中常见源文件.h头文件,.c文件 文件扩展名 源类型 .h 头文件,用于存放函数声明 .c C语言源文件,用于实现头文件中声明的方法 OC中的源文件.h头文件,.m与.mm的实现 ...