Click here to Skip to main content
16,004,529 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Working on building a Tabbed Webbrowser using CEF. It works properly until trying to create a new Window(new Form) from the a class that implements ILifeSpanHandler to catch new window events. It works when calling Form.Show() but fails when calling Form.ShowDialog() as this is being called from a different Thread. Is their a way to call ShowDialog() on new windows from another thread?

Here is how the call looks.

C#
public bool OnBeforePopup(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
{
    newBrowser = null;

    PopupWindow popup = new PopupWindow()
    {
        Url = targetUrl
    };
    popup.Show();
}


After @graeme_grant help and google have come up with a solution to use show() to act as a ShowDialog(). Below is a working solution to the problem.

C#
public bool OnBeforePopup(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
{
    newBrowser = null;
    //A big thanks to Graeme_Grant for his help 
    //with the Dispatcher.Execute(Action) example
    Dispatcher.Execute(() => 
    {
        Form form = MainWindow.ActiveForm;
        PopupWindow popupWindow = new PopupWindow()
        {
            Url = targetUrl,
            Width = 1000, 
            Height = 1000,
        };
        //Will not work properly with ShowDialog()
        //Shown/FormClosed EventHandlers are used for 
        // a workaround for ShowDialog() behavior
        popupWindow.Shown += delegate 
        { 
            form.Enabled = false; 
        };
        popupWindow.FormClosed += delegate 
        { 
            form.Enabled = true; 
        };                
        popupWindow.Show();
    });


What I have tried:

Tried calling form.ShowDialog() over Form.Show()
Posted
Updated 31-Jul-24 14:50pm
v2

1 solution

If you're not on the UI thread, then you need to switch back.

Here is an example where I have a helper class that works with the MainForm:
C#
namespace System.Windows.Threading;

public static class DispatcherHelper
{
    public static void Execute(Action action)
    {
        // no cross-thread concerns
        if (Application.OpenForms.Count == 0)
        {
            action.Invoke();
			return;
        }

		try
		{
			if (Application.OpenForms[0]!.InvokeRequired)
                // Marshall to Main Thread
				Application.OpenForms[0]?.Invoke(action);
            else
                // We are already on the Main Thread
                action.Invoke();
        }
		catch (Exception)
		{
			// ignore as might be thrown on shutting down
		}
    }
}

Then to use:
C#
DispatcherHelper.Execute(() => [run code here]);
 
Share this answer
 
Comments
charles henington 27-Jul-24 15:57pm    
This does in fact allow ShowDialog() but once shown the chromiumWebBrowser doesn't work even if readded to the form via the navigate button. Was hopping to make the main window inaccessible while a popup window was open but think I'll have to use Show() over ShowDialog(). Thank you for the excellent code example.
charles henington 31-Jul-24 20:56pm    
Have updated. Thanks much for your example that set me on the right track.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900