首页 > 解决方案 > 使用 WebView2 - Edge 创建选项卡

问题描述

当单击 webview2 - C# windows 窗体中的 Edge 中的链接时,请提供代码片段以创建选项卡而不是在新窗口中打开页面。

遵循以下步骤。

  1. 在 C# windows 窗体上拖动 webview2 控件并更新源属性链接:https ://example.com

  2. https://example.com站点在webview2中打开成功

  3. 单击站点中的几个链接 - https://example.com并打开新窗口并寻找在新选项卡中打开这个而不是在新窗口中打开它

  4. 调试代码时,此事件 webView.CoreWebView2.NewWindowRequested 从未命中。如果引发此 webView.CoreWebView2.NewWindowRequested 事件,则 webview 类上没有导航方法可用,并且它在 corewebview2 类上可用,如果我们使用它,则会获得空引用异常。

标签: c#microsoft-edgewinforms-to-webwebview2

解决方案


为了完整起见,由于 David Risney 的解释,我能够实现同样的目标。不幸的是,它没有包含任何代码,但我使用1.0.721-prereleaseand实现了这一点Microsoft.WebView2.FixedVersionRuntime.87.0.664.66.x64

程序.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');");
        }
    }
}

所以它的工作方式有点奇怪:要生成一个新窗口,你可以通过 JavaScript 使用ExecuteScriptAsync. 在这种情况下,我将打开一个新窗口到 bing.com。因此,这会调用CoreWebView2_NewWindowRequested. 为了让事件通过并且代码可以工作(否则它会冻结),它必须经历这一切。因此,您不能设置当前正在发生的事件NewWindow的内部属性。CoreWebView2NewWindowRequestedEventArgs

解决方案是将事件数据(args 和 deferral)带到新表单中,显示它,并在加载时和控件CoreWebView2属性不为 null / 已初始化后,通过调用CoreWebView2InitializationCompleted检查 args/deferral 是否不为 null 和然后将 defer 称为Complete()(这基本上就像一个 JS 承诺)并且在这里您可以将NewWindow属性设置为CoreWebView2已初始化,因此它不为空。

希望这将回答您的问题和未来的读者。使用此代码,我能够使其工作。


推荐阅读