简体   繁体   中英

Create tabs using WebView2 - Edge

Please provide the code snippet to create a tab instead of open a page in new window when click on the links in the webview2 - Edge in C# windows form.

Followed the below steps.

  1. Drag the webview2 control on C# windows form and update the source property link: https://example.com

  2. https://example.com site opened successfully in the webview2

  3. click on few links in the site - https://example.com and it opens the new window and looking for open this one in the new tab instead of open it in new window

  4. This event webView.CoreWebView2.NewWindowRequested never hit when debug the code. In case if this webView.CoreWebView2.NewWindowRequested event raised then no navigate method is available on webview class and its available on corewebview2 classs and getting the null reference exception if we use this.

There's no built in support for tabs in WebView2. However, you can intercept new windows with the NewWindowRequested event and provide your own CoreWebView2 to be that new window, and place that CoreWebView2 how you like in your UI. For instance the new CoreWebView2 could be placed in your UI to look like a new tab. (It sounds like that's what you're doing, but declaring it explicitly here just to ensure that I'm correctly understanding your scenario.)

Regarding the null WebView2.CoreWebView2 property, you can call EnsureCoreWebView2Async and await the returned task or you can set the WebView2.Source property and wait for the CoreWebView2Ready event to dispatch in order for the WebView2.CoreWebView2 property to be filled in. Its null before that.

Additionally, if you need to get the CoreWebView2 to fill in the NewWindowRequestedEventArg's NewWindow property , since the above steps for obtaining the CoreWebView2 from a WebView2 instance are both asynchronous, you'll need to call the NewWindowRequestedEventArg's GetDeferral method before starting async work in the NewWindowRequested event handler and call Complete on the Deferral once your async work is done in the NewWindowRequested event handler.

If you find cases where the WebView2 is opening new windows but the NewWindowRequested event isn't firing please open bugs at https://github.com/MicrosoftEdge/WebViewFeedback . What version of the SDK and the browser are you using with WebView2? There are some now fixed bugs with some scenarios opening new windows not firing the NewWindowRequested event.

For the sake of completeness, I was able to achieve the same thing thanks to David Risney's explanation. Unfortunately it didn't include any code, but I achieved this using 1.0.721-prerelease and Microsoft.WebView2.FixedVersionRuntime.87.0.664.66.x64 :

Program.cs:

using System;
using System.Windows.Forms;

namespace TestApp1
{
    static class Program
    {
        public static Microsoft.Web.WebView2.Core.CoreWebView2Environment WebView2Environment;

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

Form1.cs:

using System;
using System.Windows.Forms;

namespace TestApp1
{
    public partial class Form1 : Form
    {
        public Microsoft.Web.WebView2.Core.CoreWebView2Deferral Deferral;
        public Microsoft.Web.WebView2.Core.CoreWebView2NewWindowRequestedEventArgs Args;

        public Form1()
        {
            InitializeComponent();
            webView21.CoreWebView2InitializationCompleted += webView21_CoreWebView2InitializationCompleted_1;
        }

        private void CoreWebView2_NewWindowRequested(object sender, Microsoft.Web.WebView2.Core.CoreWebView2NewWindowRequestedEventArgs e)
        {
            Form1 f = new Form1();
            f.Args = e;
            f.Deferral = e.GetDeferral();
            f.Show();
        }

        private async void Form1_Load(object sender, EventArgs e)
        {
            if (Program.WebView2Environment == null)
                Program.WebView2Environment = Microsoft.Web.WebView2.Core.CoreWebView2Environment.CreateAsync(@"C:\Users\Dragon\Downloads\Microsoft.WebView2.FixedVersionRuntime.87.0.664.66.x64", $@"C:\Users\Dragon\Desktop\Test{Guid.NewGuid()}").Result;
            await webView21.EnsureCoreWebView2Async(Program.WebView2Environment);
            webView21.Source = new Uri("http://www.google.com");
        }

        private void webView21_CoreWebView2InitializationCompleted_1(object sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
        {
            if (!e.IsSuccess) { MessageBox.Show($"{e.InitializationException}"); }

            if (Deferral != null)
            {
                Args.NewWindow = webView21.CoreWebView2;
                Deferral.Complete();
            }

            webView21.CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            webView21.ExecuteScriptAsync($@"window.open('http://www.bing.com', '_blank');");
        }
    }
}

So the way this works is kinda weird: To spawn a new window, you can do it through JavaScript using ExecuteScriptAsync . In this case I'm opening a new window to bing.com. So, that makes a call to CoreWebView2_NewWindowRequested . For the event to pass and the code to work (otherwise it will freeze) it must go through it all. So, you cannot set the NewWindow property of the CoreWebView2NewWindowRequestedEventArgs inside the event that's currently happening.

The solution is to take the event data (args & deferral) to the new form, show it, and upon load and after the CoreWebView2 property of the control is not null / has initialized, by calling CoreWebView2InitializationCompleted , check if args/deferral are not null and then call the defer as Complete() (this is basically like a JS promise) AND here you can set the NewWindow property as CoreWebView2 has been initialized and therefore it's not null.

Hopefully this will answer your question and future readers. With this code, I was able to make it work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM