1. 程式人生 > >CEF Xilium.CefGlue 在當前窗體中開啟全部連結(防止彈窗)

CEF Xilium.CefGlue 在當前窗體中開啟全部連結(防止彈窗)

我們在使用Xilium.CefGlue編寫瀏覽器應用程式時。對於嵌入的網頁假設有連結會在新窗體開啟。這種使用者體驗會非常差。因此我們須要改動程式,使全部連結都在當前窗體中開啟。

首先引用Xilium.CefGlue.dll檔案。須要繼承Xilium.CefGlue 中的CefLifeSpanHandler類

namespace Xilium.CefGlue
{
    // 摘要:
    //     Implement this interface to handle events related to browser life span. The
    //     methods of this class will be called on the UI thread unless otherwise indicated.
    public abstract class CefLifeSpanHandler

繼承CefLifeSpanHandler類。並重寫OnBeforePopup方法,實現例如以下:

internal sealed class CwbLifeSpanHandler : CefLifeSpanHandler
    {
        private ChromeWebBrowser webBrowser;
        public CwbLifeSpanHandler(ChromeWebBrowser browser)
        {
            webBrowser = browser;
        }

        protected override void OnAfterCreated(CefBrowser browser)
        {
            base.OnAfterCreated(browser);
            webBrowser.OnCreated(browser);
        }

        protected override bool DoClose(CefBrowser browser)
        {
            return false;
        }

        protected override bool OnBeforePopup(CefBrowser browser, CefFrame frame, string targetUrl, string targetFrameName, CefWindowOpenDisposition targetDisposition, bool userGesture, CefPopupFeatures popupFeatures, CefWindowInfo windowInfo, ref CefClient client, CefBrowserSettings settings, ref bool noJavascriptAccess)
        {
            bool res = false;
            if (!string.IsNullOrEmpty(targetUrl))
            {
                if (webBrowser.selfRequest != null)
                {
                    CefRequest req = CefRequest.Create();
                    req.FirstPartyForCookies = webBrowser.selfRequest.FirstPartyForCookies;
                    req.Options = webBrowser.selfRequest.Options;
                    System.Collections.Specialized.NameValueCollection h = new System.Collections.Specialized.NameValueCollection();
                    h.Add("Content-Type", "application/x-www-form-urlencoded");
                    req.Set(targetUrl, webBrowser.selfRequest.Method, null, webBrowser.selfRequest.GetHeaderMap());
                    webBrowser.selfRequest = req;
                }
                //在該處實現用當前頁面開啟全部新開的窗體
                webBrowser.OpenUrl(targetUrl);
                res = true;
                if (res)
                    return res;
            }
            return base.OnBeforePopup(browser, frame, targetUrl, targetFrameName, targetDisposition, userGesture, popupFeatures, windowInfo, ref client, settings, ref noJavascriptAccess);
            return res;
            
        }
    }

儘管改動了瀏覽器的新窗體處理方法,但瀏覽器並不會自己主動載入到我們的CwbCefLifeSpanHandler類,接下來我們須要在實現CefClient的ClientBrowser類中加上我們的CwbCefLifeSpanHandler實現類:

public sealed class ClientBrowser : CefClient
{
        private readonly CwbLifeSpanHandler _lifeSpanHandler;

        private ChromeWebBrowser webBrowser;
        public ClientBrowser(ChromeWebBrowser browser)
        {
            webBrowser = browser;
            _lifeSpanHandler = new CwbLifeSpanHandler(browser);
        }

        public override CefLifeSpanHandler GetLifeSpanHandler()
        {
            return _lifeSpanHandler;
        }
}