cefsharp / CefSharp

.NET (WPF and Windows Forms) bindings for the Chromium Embedded Framework
http://cefsharp.github.io/
Other
9.87k stars 2.92k forks source link

WPF - Add Experimental LifeSpanHandler capable of hosting popups using TabControl/ContentControl #4285

Closed amaitland closed 1 year ago

amaitland commented 2 years ago

Add LifeSpanHandler implementation capable of hosting popups as Tabs/Controls

There are still some CEF bugs that mean this is still classed as experimental. One such issue was reported at https://github.com/cefsharp/CefSharp/issues/3847#issuecomment-1268346135

It's important to remember that only bugs in CefSharp can be fixed directly in this repository, CEF has it's own issue tracker at https://bitbucket.org/chromiumembedded/cef

Example:

// Open popup (browser) in a new WPF Window
// Can be used to host in TabControl/ContentControl/etc
browser.LifeSpanHandler = CefSharp.Wpf.Experimental.LifeSpanHandler
    .Create()
    .OnPopupCreated((ctrl, targetUrl, targetFrameName, windowInfo) =>
    {
        var windowX = (windowInfo.X == int.MinValue) ? double.NaN : windowInfo.X;
        var windowY = (windowInfo.Y == int.MinValue) ? double.NaN : windowInfo.Y;
        var windowWidth = (windowInfo.Width == int.MinValue) ? double.NaN : windowInfo.Width;
        var windowHeight = (windowInfo.Height == int.MinValue) ? double.NaN : windowInfo.Height;
        var popup = new System.Windows.Window
        {
            Left = windowX,
            Top = windowY,
            Width = windowWidth,
            Height = windowHeight,
            Content = ctrl,
            Owner = Window.GetWindow(browser),
            Title = targetFrameName
        };
        popup.Closed += (o, e) =>
        {
            var w = o as System.Windows.Window;
            if (w != null && w.Content is IWebBrowser)
            {
                (w.Content as IWebBrowser)?.Dispose();
                w.Content = null;
            }
        };
    })
    .OnPopupBrowserCreated((ctrl, browser) =>
    {
        ctrl.Dispatcher.Invoke(() =>
        {
            var owner = System.Windows.Window.GetWindow(ctrl);
            if (owner != null && owner.Content == ctrl)
            {
                owner.Show();
            }
        });
    })
    .OnPopupDestroyed((ctrl, popupBrowser) =>
    {
        //If browser is disposed then we don't need to remove the tab
        if (!ctrl.IsDisposed)
        {
            var owner = System.Windows.Window.GetWindow(ctrl);
            if (owner != null && owner.Content == ctrl)
            {
                owner.Close();
            }
        }
    }).Build();
amaitland commented 2 years ago

The delegates have been renamed to add a LifeSpanHandler prefix.

This will be included in M107