2011-02-14 60 views

回答

6

是的。 WebFrowser控件的WPF真的是braindead。最重要的是它甚至是密封的。

您必須使用Windows.Forms的WebBrowser控件並將其嵌入到WindowsFormsHost中。

此外,你必須從WebBrowser派生出一個類,並在其中做一些COM魔術。

做一個用戶控件這樣的:

<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的web瀏覽器這樣的:

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 
} 
} 

然後使用web瀏覽器(它的命名一樣,在XAML)從代碼隱藏併爲AdditionalHeaders提供所需的值。

相關問題