【问题标题】:e.NewWindow = (CoreWebView2)sender still results in a separate instancee.NewWindow = (CoreWebView2)sender 仍然会产生一个单独的实例 c#
【发布时间】:2021-10-17 07:18:52
【问题描述】:

我想导航到 URL,而不是打开一个单独的实例。 无论我做什么,它仍然会打开另一个 webview 实例。

private void CoreWebView2_NewWindowRequested(object sender,
            CoreWebView2NewWindowRequestedEventArgs e)
        {
            //e.NewWindow = webView21.CoreWebView2;
            e.NewWindow = (CoreWebView2)sender;
            //e.Handled = true;
        }

here's the original post,我需要怎么做才能让它处理新窗口请求?

【问题讨论】:

    标签: c# event-handling webview2


    【解决方案1】:

    要在请求新的弹出窗口时接收通知,请订阅 CoreWebView2 的NewWindowRequested

    当有生成弹出窗口的请求时引发该事件。单击只会导致浏览器导航到不同 URI 的链接不会引发事件(无弹出窗口)。
    如果用户单击浏览器提供的标准 ContextMenu 的 Open link in new window (sic) 选项,则可以请求新的弹出窗口。
    或者如果网页在没有用户干预的情况下生成一个。

    不幸的是,e.IsUserInitiated 属性始终为true,因此您可能很难确定(不注入 JavaScript)是否应该阻止弹出窗口(如果您愿意的话)。

    当请求一个新的弹窗时,你可以随意设置e.Handled = true来阻止它。

    如果您想打开同一个窗口的新窗口 URI,您可以指定:

    e.Handled = true;
    e.NewWindow = (CoreWebView2)sender;
    // or  
    e.Handled = true;
    ((CoreWebView2)sender).Navigate(e.Uri);
    

    示例 WebView2 主处理程序表单:

    using Microsoft.Web.WebView2.Core;
    
    public partial class MainForm : Form
    {
        public MainForm() => InitializeComponent();
    
        protected override async void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            webView2.CoreWebView2InitializationCompleted += OnCoreWebView2InitializationCompleted;
            var env = await CoreWebView2Environment.CreateAsync(null, null, null);
            await webView2.EnsureCoreWebView2Async(env);
            webView2.Source = new Uri("https://www.somesite.com");
        }
    
        private void OnCoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
        {
            webView2.CoreWebView2.NewWindowRequested += OnNewWindowRequested;
        }
    
        private void OnNewWindowRequested(object sender, CoreWebView2NewWindowRequestedEventArgs e)
        {
            // Open the Uri requested in the current Window
            e.Handled = true;
            ((CoreWebView2)sender).Navigate(e.Uri);
        }
      
        // Or, if you want to handle Popup Windows using your own Form template
        // => Note that it's the same event handler as above, pick one, not both!
        private void OnNewWindowRequested(object sender, CoreWebView2NewWindowRequestedEventArgs e)
        {
            // Open the Uri requested in a new instance of the PopupWindow Form
            var deferral = e.GetDeferral();
            e.Handled = true;
            var popup = new PopupWindow(deferral, e);
            popup.Show();
        }
    }
    

    如果您想创建一个显示弹出窗口的新表单,则需要一个接收由e.GetDeferral() 返回的CoreWebView2Deferral 的表单模板(它可以只是一个包含 WebView2 控件的表单)。

    在这个Form的初始化过程中检查CoreWebView2Deferral对象是否为空。如果不是,请通过调用其Complete() 方法来完成延迟事件。

    然后订阅NewWindowRequested 事件以在请求新弹出窗口时执行相同的操作(除非您想阻止它)。

    当然,您可以在选项卡式控件中显示这些表单,以生成标准的选项卡式视图,这在所有 Web 浏览器中都很常见。

    示例PopupWindow表单

    using Microsoft.Web.WebView2.Core;
    using System.Windows.Forms;
    
    public partial class PopupWindow : Form
    {
        public PopupWindow() => InitializeComponent();
        public PopupWindow(CoreWebView2Deferral deferral, CoreWebView2NewWindowRequestedEventArgs args) 
            : this() {
            Core2Deferral = deferral;
            NewWindowArgs = args;
        }
    
        protected virtual CoreWebView2Deferral Core2Deferral { get; private set; }
        protected virtual CoreWebView2NewWindowRequestedEventArgs NewWindowArgs { get; private set; }
    
        protected async override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            webView2.CoreWebView2InitializationCompleted += OnCoreWebView2InitializationCompleted;
    
            var env = await CoreWebView2Environment.CreateAsync(null, null, null);
            await webView2.EnsureCoreWebView2Async(env);
        }
    
        private void OnCoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
        {
            webView2.CoreWebView2.Settings.AreDefaultContextMenusEnabled = true;
            if (Core2Deferral != null) {
                NewWindowArgs.NewWindow = webView2.CoreWebView2;
                Core2Deferral.Complete();
            }
            webView2.CoreWebView2.NewWindowRequested += OnNewWindowRequested;
        }
    
        private void OnNewWindowRequested(object sender, CoreWebView2NewWindowRequestedEventArgs e)
        {
            e.Handled = true;
            var popup = new PopupWindow(e.GetDeferral(), e);
            popup.Show();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-16
      • 2019-08-05
      • 2012-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多