原文:CefSharp中ChromiumWebBrowser打开新页面处理(_blank)

版权声明:欢迎转载,但是请保留出处说明 https://blog.csdn.net/lanwilliam/article/details/79640954

CefSharp的Browser怎么说也是嵌入了Chromium的浏览器,所以碰到<a >标签“_blank”这样的时候,都是弹出新窗体打开新页面。

但是怎奈我使用了DevExpress控件中的TabForm这个东西来作为主窗体,所以我不希望弹出新的窗体来,那么就需要捕获打开新窗体这样一个事件来重写了。

但是你会发现,在ChromiumWebBrowser对象中,没有OnNewWindow这类的事件啊,怎么办,难道到此为止了吗?!

果然百度还是无能为力,科学上网找google查了一下。CefSharp通过另一个对象处理的这类事件。CefLifeSpanHandler,就是这个东西了。里面提供了我们要用的事件,不废话,上代码。

    public class CefLifeSpanHandler : CefSharp.ILifeSpanHandler
{
public CefLifeSpanHandler()
{ } public bool DoClose(IWebBrowser browserControl, CefSharp.IBrowser browser)
{
if (browser.IsDisposed || browser.IsPopup)
{
return false;
} return true;
} public void OnAfterCreated(IWebBrowser browserControl, IBrowser browser)
{ } public void OnBeforeClose(IWebBrowser browserControl, IBrowser browser)
{
} public bool OnBeforePopup(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
{
var chromiumWebBrowser = (ExtChromiumBrowser)browserControl; chromiumWebBrowser.Invoke(new Action(() =>
{
NewWindowEventArgs e = new NewWindowEventArgs(windowInfo, targetUrl);
chromiumWebBrowser.OnNewWindow(e);
})); newBrowser = null;
return true;
}
}

这是Handler的实现。

然后需要封装一下ChromiumWebBrowser,提供OnNewWindow事件。

    public class ExtChromiumBrowser : ChromiumWebBrowser
{
public ExtChromiumBrowser()
: base(null)
{
this.LifeSpanHandler = new CefLifeSpanHandler();
//this.DownloadHandler = new DownloadHandler(this);
} public ExtChromiumBrowser(string url) : base(url)
{
this.LifeSpanHandler = new CefLifeSpanHandler();
} public event EventHandler<NewWindowEventArgs> StartNewWindow; public void OnNewWindow(NewWindowEventArgs e)
{
if (StartNewWindow != null)
{
StartNewWindow(this, e);
}
}
}

含有事件参数定义

    public class NewWindowEventArgs : EventArgs
{
private IWindowInfo _windowInfo;
public IWindowInfo WindowInfo
{
get { return _windowInfo; }
set { value = _windowInfo; }
}
public string url { get; set; }
public NewWindowEventArgs(IWindowInfo windowInfo, string url)
{
_windowInfo = windowInfo;
this.url = url;
}
}

然后我们用新定义的ExtChromiumBrowser替换之前的ChromiumWebBrowser,并且实现相关代码。

        public void InitBrowser()
{
Cef.Initialize(new CefSettings());
browser = new ExtChromiumBrowser("http://124.128.61.90:10080/login.html");
//this.Controls.Add(browser);
tabFormContentContainer1.Controls.Add(browser);
browser.Dock = DockStyle.Fill;
browser.StartNewWindow += Browser_StartNewWindow;
browser.TitleChanged += OnBrowserTitleChanged;
browser.FrameLoadEnd += browser_FrameLoadEnd;
CefSharpSettings.LegacyJavascriptBindingEnabled = true;
browser.RegisterJsObject("jsObj", new SendCarBillPrint());
//browser.JavascriptObjectRepository.Register("jsObj", new SendCarBillPrint(), false);
}

然后是StartNewWindow的事件实现。

        private void Browser_StartNewWindow(object sender, NewWindowEventArgs e)
{
TabFormPage tp = new TabFormPage();
tp.Text = "新窗口";
TabFormContentContainer tc1 = new TabFormContentContainer();
tp.ContentContainer = tc1;
tc1.Dock = DockStyle.Fill;
var control = new ExtChromiumBrowser(e.url);
control.Dock = DockStyle.Fill;
//control.CreateControl();
//host.Child = control;
control.Focus(); tc1.Controls.Add(control);
tabFormControl1.Pages.Add(tp);
tabFormControl1.SelectedPage = tp;
tp.Text = control.Text;
control.StartNewWindow += Browser_StartNewWindow;
control.TitleChanged += OnBrowserTitleChanged;
//e.WindowInfo.SetAsChild(control.Handle, 0, 0, (int)host.ActualWidth, (int)host.ActualHeight);
}

这样就实现了拦截打开窗口事件,并且在新tab中打开了。

需要注意的是,OnBeforePopup 事件中,return true后,ChromiumWebBrowser就不会再打开新窗口了。我这里手动创建了新的Tab页,然后添加了Browser,然后将拦截的url设置上去,实现了新tab的显示。但其实这样做并非最优,我这里是为解决DevExpress的Tab窗体控件问题才这么搞的。

注意看我之前注释的代码。

e.WindowInfo.SetAsChild(control.Handle, 0, 0, (int)host.ActualWidth, (int)host.ActualHeight);

其实这才是正确的办法。

在OnBeforePopup 事件中返回false。然后在Browser_StartNewWindow事件中,通过上面SetAsChild方法设置才是好的办法。原理是将新打开窗体的设置到Control.Handle上去了。Control可以是个窗体,也可以是个Panel之类的Control,设置好大小。这样原则上只开了一个Browser对象。道理上应该性能好一点。

但是,注意了,但是,我本来想优化一下来着,发现在windows任务管理器中,其实也是两个进程,加上DevExpress好多资料不好找,于是就先这样了。有空再说吧。

至此,基本上Winform嵌入ChromiumWebBrowser的必要功能就全了,可以应用了。

希望对大家有帮助。

抱歉,没想到加QQ好友的这么多,暂时不接受好友申请了,上限了。大家 还是留言吧。

CefSharp中ChromiumWebBrowser打开新页面处理(_blank)的更多相关文章

  1. Web设计中打开新页面或页面跳转的方法 js跳转页面

    Web设计中打开新页面或页面跳转的方法 一.asp.net c# 打开新页面或页面跳转 1. 最常用的页面跳转(原窗口被替代):Response.Redirect("newpage.aspx ...

  2. Web设计中打开新页面或页面跳转的方法

    一.asp.net c# 打开新页面或页面跳转 1. 最常用的页面跳转(原窗口被替代):Response.Redirect("newpage.aspx"); 2. 利用url地址打 ...

  3. jq中打开新页面 并获取携带值

    打开新页面:window.location.href = "./index.html?id=1"获取携带值: function GetRequest() { var url = l ...

  4. 模态对话框中的window.close关闭时会打开新页面

    在模态对话框的页面的<head></head>加上<base target="_self"> 就不会打开新页面了.

  5. JavaScript关闭窗口的同时打开新页面的方法

    做网页的时候需要弹出一个小窗口,然后要实现一个功能就是鼠标点击超链接关闭小窗口并打开一个新页面,就如同下图: 这是一个小窗口,点击超链接这个窗口会关闭并且会正常在浏览器打开新页面,首先写js关闭窗口的 ...

  6. DTcms手机版使用余额支付 提示信息跳转到PC版的错误。以及提交订单不打开新页面

    手机版使用余额支付 提示信息跳转到PC版的错误 引起错误的原因是中间需要提交到DTcms.Web\api\payment\balance\index.aspx去处理 导致BasePage.cs中的li ...

  7. ASP.NET 后台打开新页面

    [TOC] Response.Write 这是最常见的后台打开新页面的方法. Response.Write("<script>window.open('~/FileView.as ...

  8. 点击iframe窗口里的超链接,打开新页面的方式

    点击iframe窗口里的超链接打开新页面的方式: a标签中设置按钮点击事件,事件调用的方法使用如下方法跳转链接:  window.open('url链接', '_blank');

  9. 如何使a标签打开新页面并阻止刷新当前页面

    错误: HTML中,使用href属性时,当前页面和新页面均跳转到URL指定的页面,即当前页面也刷新: <li id='goToBack'><a href='**.action' ta ...

随机推荐

  1. js进阶ajax基本用法(创建对象,连接服务器,发送请求,获取服务器传过来的数据)

    js进阶ajax基本用法(创建对象,连接服务器,发送请求,获取服务器传过来的数据) 一.总结 1.ajax的浏览器的window对象的XMLHtmlRequest对象的两个重要方法:open(),se ...

  2. php随机字符串

    <?php class RandChar{ function getRandChar($length){ $str = null; $strPol = "ABCDEFGHIJKLMNO ...

  3. Centos6.5 网络配置

    网络配置 本教程配置说明 以下为本教程安装时的配置,用户依据实际情况进行调整 * 在root用户权限下安装下完毕 * IP地址设置为 10.10.108.160 * 本机DNS设置为 8.8.8.8 ...

  4. javaScript_with用法

    with语句用途 暂时改变作用域链.简化代码. 语法结构 with(object){ //其他语句 } 例1 with(person){ name= "zhang"; addres ...

  5. 【u012】数字游戏

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 小W发明了一个游戏,他在黑板上写出了一行数字a1,a2,-an,然后给你m个回合的机会,每回合你可以从 ...

  6. mysqlsla安装

    #下载mysqlsla https://github.com/daniel-nichter/hackmysql.com   yum install perl-ExtUtils-CBuilder per ...

  7. 卷积神经网络Lenet-5实现

    卷积神经网络Lenet-5实现 原文地址:http://blog.csdn.net/hjimce/article/details/47323463 作者:hjimce 卷积神经网络算法是n年前就有的算 ...

  8. System and method for dynamically adjusting to CPU performance changes

    FIELD OF THE INVENTION The present invention is related to computing systems, and more particularly ...

  9. XMPP之安装mySQL--Mac OS(一)

    come from:http://www.cnblogs.com/xiaodao/archive/2013/04/04/2999426.html 一.安装 到MySQL官网上http://dev.my ...

  10. 推荐一款软件mybatis-generator-gui

    https://github.com/zouzg/mybatis-generator-gui mybatis-generator-gui mybatis-generator-gui是基于mybatis ...