1、实现ILifeSpanHandler接口,为了支持带type="POST" target="_blank"的链接,并且为了后面能够获取到ChromiumWebBrowser并释放旧的ChromiumWebBrowser,新窗体还是要让它弹的,只不过后面会隐藏它,代码如下:
class="code_img_closed" src="/Upload/Images/2017102315/0015B68B3C38AA5B.gif" alt="" />logs_code_hide('c4c8ca03-121e-4514-bcfa-4112ac122b8f',event)" src="/Upload/Images/2017102315/2B1B950FA3DF188F.gif" alt="" />using CefSharp; using CefSharp.WinForms; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace MyBrowser { 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, IWindowInfo windowInfo, ref bool noJavascriptAccess, out IWebBrowser newBrowser) { var chromiumWebBrowser = (ExtChromiumBrowser)browserControl; ExtChromiumBrowser extBrowser = new ExtChromiumBrowser(targetUrl) { Dock = DockStyle.Fill }; var windowX = windowInfo.X; var windowY = windowInfo.Y; var windowWidth = (windowInfo.Width == int.MinValue) ? 600 : windowInfo.Width; var windowHeight = (windowInfo.Height == int.MinValue) ? 800 : windowInfo.Height; chromiumWebBrowser.Invoke(new Action(() => { var popup = new Form { Left = windowX, Top = windowY, Width = windowWidth, Height = windowHeight, Text = targetFrameName }; popup.CreateControl(); var control = new Control(); control.Dock = DockStyle.Fill; control.CreateControl(); popup.Controls.Add(control); popup.Show(); var rect = control.ClientRectangle; windowInfo.SetAsChild(control.Handle, rect.Left, rect.Top, rect.Right, rect.Bottom); NewWindowEventArgs e = new NewWindowEventArgs(extBrowser, targetUrl, popup); chromiumWebBrowser.OnNewWindow(e); })); newBrowser = null; return false; } } }View Code
2、使用ILifeSpanHandler接口:
using CefSharp.WinForms; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms.Integration; namespace MyBrowser { public class ExtChromiumBrowser : ChromiumWebBrowser { public ExtChromiumBrowser() : base("about:_blank") { this.LifeSpanHandler = new CefLifeSpanHandler(); this.DownloadHandler = new DownloadHandler(this); } public ExtChromiumBrowser(string adress) : base(adress) { this.LifeSpanHandler = new CefLifeSpanHandler(); this.DownloadHandler = new DownloadHandler(this); } public event EventHandler<NewWindowEventArgs> StartNewWindow; public void OnNewWindow(NewWindowEventArgs e) { if (StartNewWindow != null) { StartNewWindow(this, e); } } } }View Code
3、定义NewWindowEventArgs:
using CefSharp; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace MyBrowser { public class NewWindowEventArgs : EventArgs { private ExtChromiumBrowser _browser; public ExtChromiumBrowser Browser { get { return _browser; } set { value = _browser; } } private string _url; public string Url { get { return _url; } set { value = _url; } } private Form _form; public Form Form { get { return _form; } set { value = _form; } } public NewWindowEventArgs(ExtChromiumBrowser browser, string url, Form form) { _url = url; _browser = browser; _form = form; } } }View Code
4、实现StartNewWindow,在StartNewWindow事件中做了三件事,一是替换掉旧的ChromiumWebBrowser,二是释放掉旧的ChromiumWebBrowser,三是隐藏弹出的新窗体,实际效果可能会看到Windows任务栏的图标会闪一下消失,那就是弹出的新窗体被隐藏了。这个实现方法比较变态,但是如果不让新窗体弹出,就不支持带type="POST" target="_blank"的链接,因为没有把数据POST到服务器,如果让新窗体弹出,但是使用新窗体中的Control作为Child,而不new一个新的ChromiumWebBrowser,那么找不到新ChromiumWebBrowser,虽然它可以正常显示,但获取不到它,后面无法释放。
private void Window_Loaded(object sender, RoutedEventArgs e) { _browser = new ExtChromiumBrowser() { Dock = DockStyle.Fill }; BindBrowser(_browser); _browser.FrameLoadEnd += FrameLoadEnd; _browser.Load(_tokenUrl); host.Child = _browser; } private void BindBrowser(ExtChromiumBrowser browser) { browser.StartNewWindow += (s, e) => { this.Dispatcher.BeginInvoke(new Action(() => { _browser = e.Browser; BindBrowser(e.Browser); host.Child = e.Browser; e.Browser.FrameLoadStart += (ss, ee) => { this.Dispatcher.BeginInvoke(new Action(() => { (ss as ExtChromiumBrowser).Focus(); })); }; e.Form.Visible = false; Task.Factory.StartNew(() => { Thread.Sleep(1000); this.Dispatcher.BeginInvoke(new Action(() => { e.Form.Dispose(); browser.Dispose(); })); }); })); }; }View Code