Search code examples
c#.netwpfchromiumwebview2

Opening the URL in child window using the CoreWebView2NewWindowRequestedEventArgs


In my WPF WebView2 control, I want to execute the window.open("https://www.google.com") from the main window to open the URL in the child window using the CoreWebView2_NewWindowRequested. But the URL webpage is not getting displayed in the child window instance.

I am quite not sure what is wrong with my below piece of code:

MainWindow.xaml.cs

  private async void btnOpenPopup_Click(object sender, RoutedEventArgs e)
  {
     await MainWebView2Instance.ExecuteScriptAsync("openPopup()");
  }

  private async void CoreWebView2_NewWindowRequested(object sender, CoreWebView2NewWindowRequestedEventArgs e)
  {
    Microsoft.Web.WebView2.Core.CoreWebView2Deferral deferral = e.GetDeferral();
    MainWindow childWindow = new MainWindow();
    childWindow.Title = "Child Window";

    //Creating a new webview2 instance for the child window
    WebView2 childWebView2Instance = new WebView2();
    await childWebView2Instance.EnsureCoreWebView2Async(null);

    childWebView2Instance.Source = new Uri(e.Uri);

    childWindow.dockPanel.Children.Add(childWebView2Instance);

    e.Handled = true;
    deferral.Complete();
    childWindow.Show();
  }

JavaScript in HTML Page

<script type="text/javascript">
   function openPopup() {
            window.open("https://www.google.com ");
        }
</script>

Solution

  • Comment out (or remove) the following line:

    await childWebView2Instance.EnsureCoreWebView2Async(null);
    

    -- it's blocking. You aren't using CoreWebView2Environment, so it's usage is unnecessary. When you set the Source property for childWebView2Instance, it will implicitly initialize CoreWebView2.

    Update:

    The following code will open a child window when a link on a web page is clicked where the HTML of the web page is the following:

    index.html

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    
    <html>
    
    <head>
    </head>
    
    <script>
      function popuponclick()
      {
         my_window = window.open("https://www.google.com");
      }
    
    </script>
    
    <body>
    
      <div>
        <a href="javascript: popuponclick()">Open Popup Window</A>
      </div>
    
    </body>
    </html>
    

    MainWindow.xaml

             ...
    
    <wv2:WebView2 
    Name="webView21"
    CoreWebView2InitializationCompleted="webView21_CoreWebView2InitializationCompleted" 
    Source="http://127.0.0.1:80/index.html"/>
    
             ...
    

    webView21_CoreWebView2InitializationCompleted (MainWindow.xaml.cs)

    private void webView21_CoreWebView2InitializationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine(this.Title + " - webView21_CoreWebView2InitializationCompleted");
        webView21.CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested;
    }
    

    Add using statements to MainWindow.xaml.cs:

    using Microsoft.Web.WebView2.Core;
    using Microsoft.Web.WebView2.Wpf;
    

    In MainWindow.xaml.cs, add another constructor which can be used to set the Source property for the WebView2 control. It should look like the following:

    Constructors: (MainWindow.xaml.cs)

             ...
    
    public MainWindow()
    {
        InitializeComponent();
    }
    
    public MainWindow(string url)
    {
        InitializeComponent();
    
        webView21.Source = new Uri(url);
    }
    
             ...
    

    CoreWebView2_NewWindowRequested (MainWindow.xaml.cs)

    private void CoreWebView2_NewWindowRequested(object sender, Microsoft.Web.WebView2.Core.CoreWebView2NewWindowRequestedEventArgs e)
    {
        CoreWebView2 cwv2 = (CoreWebView2)sender;
    
        Microsoft.Web.WebView2.Core.CoreWebView2Deferral deferral = e.GetDeferral();
    
        MainWindow childWindow = null;
        childWindow = new MainWindow(e.Uri);
        childWindow.Title = "Child Window";
        childWindow.Show();
    
        e.Handled = true;
        deferral.Complete();
    }