在使用WPF浏览器控件时,如何覆盖ie的BeforeNavigate2? [英] How can I overlop ie's BeforeNavigate2 when using the WPF Browser Control?

查看:59
本文介绍了在使用WPF浏览器控件时,如何覆盖ie的BeforeNavigate2?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我了解,WPF的Brwoser控件是对Active-X控件的包装.后者具有BeforeNavigate2方法,而我在WPF WebBrowser控件中找不到此方法.有办法解决这个问题吗?

As far as I understand, WPF's Brwoser control is a wrapper of the ie Active-X control. The later has a BeforeNavigate2 Method, while I don't find this in the WPF WebBrowser control. Is there a way I can work around this?

谢谢!马克

推荐答案

是.WPF的WebBrowser控件确实死了.最重要的是,它甚至被密封了.

Yes. The WebBrowser control of WPF is really braindead. On top of that it is even sealed.

您必须使用Windows.Forms的WebBrowser控件并将其嵌入WindowsFormsHost中.

You have to use the WebBrowser control of Windows.Forms and embed it in a WindowsFormsHost.

此外,您还必须从WebBrowser派生一个类并在其中进行一些COM魔术操作.

Additionally you have to derive a class from WebBrowser and do some COM magic in it.

像这样制作一个UserControl:

Make a UserControl like this:

<UserControl x:Class="MP.Assistant.WpfClient.DialogContentControls.WebBrowserHost"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:DialogContentControls="clr-namespace:MP.Assistant.WpfClient.DialogContentControls"
         mc:Ignorable="d"
         d:DesignHeight="300"
         d:DesignWidth="300">
<Grid Name="BrowserHost">
    <WindowsFormsHost>
        <DialogContentControls:ExtendedWinFormsWebBrowser x:Name="WebBrowser" />
    </WindowsFormsHost>
</Grid>

然后按如下所示修改Windows.Forms WebBrowser:

Then modify Windows.Forms WebBrowser like this:

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Windows.Forms;

namespace MP.Assistant.WpfClient.DialogContentControls
{
    /// Imports the BeforeNavigate2 method from the OLE DWebBrowserEvents2 
    /// interface. 
    [ComImport]
    [Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    [TypeLibType(TypeLibTypeFlags.FHidden)]
    public interface DWebBrowserEvents2
    {
        [PreserveSig]
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =    MethodCodeType.Runtime)]
    [DispId(250)] 

    void BeforeNavigate2([In] [MarshalAs(UnmanagedType.IDispatch)] object pDisp,
                         [In] [MarshalAs(UnmanagedType.Struct)] ref object URL,
                         [In] [MarshalAs(UnmanagedType.Struct)] ref object Flags,
                         [In] [MarshalAs(UnmanagedType.Struct)] ref object TargetFrameName,
                         [In] [MarshalAs(UnmanagedType.Struct)] ref object PostData,
                         [In] [MarshalAs(UnmanagedType.Struct)] ref object Headers,
                         [In] [Out] ref bool Cancel);
}

public class ExtendedWinFormsWebBrowser : WebBrowser
{
    // Handles the NavigateError event from the underlying ActiveX 
    // control by raising the NavigateError event defined in this class.
    AxHost.ConnectionPointCookie cookie;
    ExtendedWinFormsWebBrowserEventHelper helper;
    bool renavigating;

    public ExtendedWinFormsWebBrowser()
    {
        AdditionalHeaders = new string[] {};
    }

    public string[] AdditionalHeaders { get; set; }

    [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
    protected override void CreateSink()
    {
        base.CreateSink();

        // Create an instance of the client that will handle the event
        // and associate it with the underlying ActiveX control.
        helper = new ExtendedWinFormsWebBrowserEventHelper(this);
        cookie = new AxHost.ConnectionPointCookie(ActiveXInstance, helper, typeof (DWebBrowserEvents2));
    }

    [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
    protected override void DetachSink()
    {
        // Disconnect the client that handles the event
        // from the underlying ActiveX control.
        if (cookie != null)
        {
            cookie.Disconnect();
            cookie = null;
        }
        base.DetachSink();
    }

    void OnBeforeNavigate2(object pDisp,
                           ref object url,
                           ref object flags,
                           ref object targetFrameName,
                           ref object postData,
                           ref object headers,
                           ref bool cancel)
    {
        if (!renavigating)
        {
            if (AdditionalHeaders.Length > 0)
            {
                headers += string.Join("\r\n", AdditionalHeaders) + "\r\n";
                renavigating = true;
                cancel = true;
                Navigate((string)url, (string)targetFrameName, (byte[])postData, (string)headers);
            }
        }
        else
        {
            renavigating = false;
        }
    }

    #region Nested type: ExtendedWinFormsWebBrowserEventHelper

    class ExtendedWinFormsWebBrowserEventHelper : StandardOleMarshalObject, DWebBrowserEvents2
    {
        readonly ExtendedWinFormsWebBrowser parent;

        public ExtendedWinFormsWebBrowserEventHelper(ExtendedWinFormsWebBrowser parent)
        {
            this.parent = parent;
        }

        #region DWebBrowserEvents2 Members

        public void BeforeNavigate2(object pDisp,
                                    ref object URL,
                                    ref object Flags,
                                    ref object TargetFrameName,
                                    ref object PostData,
                                    ref object Headers,
                                    ref bool Cancel)
        {
            parent.OnBeforeNavigate2(pDisp,
                ref URL,
                ref Flags,
                ref TargetFrameName,
                ref PostData,
                ref Headers,
                ref Cancel);
        }

        #endregion
    }

    #endregion
}
}

然后从您的代码隐藏中使用WebBrowser(其名称类似于XAML),并为AdditionalHeaders提供所需的值.

Then use WebBrowser (its named like that in XAML) from your code-behind and provide AdditionalHeaders with the required value.

这篇关于在使用WPF浏览器控件时,如何覆盖ie的BeforeNavigate2?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆