In this post, I'll show how to simply capture the open event of a pop-up, stop this event and open it wherever you wish.
Introduction
CefSharp
is a powerful embedding of Chrome that allows you to customize a browser to perform the most diverse tasks of the day-to-day. As an example, we can mention: read authentication cookies of the sites that must be sign in, intercept pop up loaded by sites, among other necessities.
In the lines below, I'll show you how to simply capture the open event of a pop-up, stop this event and open it wherever you wish.
To do this, we use the CefSharp
interface, called IlifeSpanHandler
.
ILifeSpanHandler
has 4 events (OnBeforePopup
, DoClose
, OnBeforeClose
and OnAfterCreated
) and they are responsible for handling all pop up events. For this task, I'll use only the OnBeforePopup
event.
Background
For design, I used:
- Microsoft .NET Framework 4.6.1
CefSharp
available in the NuGet Package - Windows Forms Application
- Visual Studio 2017
Using the Code
This article is a complement for projects created with CefSharp
.
If you don't know how to create a new project, click here to learn.
For using this interface:
- Create a class within the project Inheriting this interface:
public class LifespanHandler: ILifeSpanHandler
- Create the event for receiving the url of the pop up:
public event Action<string> popup_request;
- In the
OnBeforePopup
event, send the url to the event of item 2 and stop the popup that is opening:
this.popup_request?.Invoke(targetUrl);
newBrowser = null;
- Type the other events in the class. They have no source code.
When we forget to declare the signature of all interface events in the class, even if they are not used, this error "'popup_cefsharp.LifespanHandler' does not implement interface member 'CefSharp.ILifeSpanHandler.OnAfterCreated(CefSharp.IWebBrowser, CefSharp.IBrowser)'
" happens.
Below is the complete code class:
using CefSharp;
using CefSharp.WinForms;
namespace popup_cefsharp
{
public class LifespanHandler: ILifeSpanHandler
{
public event Action<string> popup_request;
bool ILifeSpanHandler.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)
{
this.popup_request?.Invoke(targetUrl);
newBrowser = null;
return true;
}
bool ILifeSpanHandler.DoClose(IWebBrowser browserControl, IBrowser browser)
{ return false; }
void ILifeSpanHandler.OnBeforeClose(IWebBrowser browserControl, IBrowser browser){}
void ILifeSpanHandler.OnAfterCreated(IWebBrowser browserControl, IBrowser browser) {}
}
}
Inside of the form, the class LifeSpanHandler
is initialized and attributed in the variable of the browser.
LifespanHandler life = new LifespanHandler();
chrome.LifeSpanHandler = life;
Create the event for url of the pop up captured:
private void life_popup_request(string obj){}
Add the event in the variable of the class LifeSpanHandler
:
life.popup_request += life_popup_request;
Below is the complete code. This code was typed inside of the Windows Form.
using CefSharp;
using CefSharp.WinForms;
namespace popup_cefsharp
{
public partial class frm_main : Form
{
public frm_main()
{
InitializeComponent();
}
ChromiumWebBrowser chrome, chrome_popup;
private void initialize_browser()
{
try
{
CefSettings settings = new CefSettings();
Cef.Initialize(settings);
chrome = new ChromiumWebBrowser(this.txt_url.Text.Trim());
LifespanHandler life = new LifespanHandler();
chrome.LifeSpanHandler = life;
life.popup_request += life_popup_request;
this.pan_container.Controls.Add(chrome);
chrome.Dock = DockStyle.Fill;
chrome_popup = new ChromiumWebBrowser("");
this.pan_container_popup.Controls.Add(chrome_popup);
chrome_popup.Dock = DockStyle.Fill;
}
catch (Exception ex)
{
MessageBox.Show("Error in initializing the browser. Error: " + ex.Message);
}
}
private void carregar_popup_new_browser(string url)
{
chrome_popup.Load(url);
}
private void frm_main_FormClosing(object sender, FormClosingEventArgs e)
{
Cef.Shutdown();
Application.Exit();
}
private void frm_main_Load(object sender, EventArgs e)
{
this.initialize_browser();
}
private void life_popup_request(string obj)
{
this.carregar_popup_new_browser(obj);
}
}
}
Points of Interest
When you try to manipulate an object, other than the browser, in the life_popup_request
event, the project generates an exception.
For correct, use invoke delegate. Example:
private void life_popup_request(string obj)
{
chrome_popup = new ChromiumWebBrowser(url);
this.Invoke((MethodInvoker)delegate()
{
this.pan_container_popup.Controls.Clear();
this.pan_container_popup.Controls.Add(chrome_popup);
});
chrome_popup.Dock = DockStyle.Fill;
}
References
History
- July 2017: Version 1 - Publication of the article
- February 2021: Version 2 - Update of
CefSharp
to version 87, Visual Studio version 2017, .NET version 4.6.1