WPFでmshtml使わずにWebBrowserのDocumentを読む方法

WPFのSystem.Windows.Control.WebBrowserのDocumentプロパティをウォッチ式で見てみると,mshtml.HTMLDocumentClass のインスタンスが見えていました.IEが保持しているドキュメントのインスタンスがそのまま外部公開されているっぽいです.

このインスタンスをコードで参照するには,プロジェクトの参照にmshtmlを追加してやらないとだめです.そこで,mshtmlを参照しなくてもHTMLDocumentを読む方法はというと,.NET 2.0で追加されたSystem.Windows.Forms.WebBrowser を使うのがよさそうです.すでにWPFではなくなっていますが,WebBrowserがWPFの外にあるIEのラッパなのですから,ここはあきらめます.

まずWPFでFormsをホストするためのXAMLを書きます.次に,プロジェクトの参照に,WindowsFormsIntegrationを追加します.

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:wf="clr-namespace:System.Windows.Forms.Integration;assembly=windowsformsintegration"
    Title="Window1">
        <wf:WindowsFormsHost 
            Name="wfHost"/>
</Window>

次にC#で,ブラウザのインスタンス追加,およびドキュメント読み込み時の処理を書きます.ドキュメントを参照するタイミングにDocumentCompletedイベントを使います.System.Windows.Forms.WebBrowserは,WPFのSystem.Windows.Controls.WebBrowserと違って,DocumentTitleなどHTMLドキュメントの中身を簡単に参照するプロパティがあって,便利です.

using ...省略...
using WinForms = System.Windows.Forms;
namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        System.Windows.Forms.WebBrowser _browser;
        public Window1()
        {
            InitializeComponent();
            // WebBrowser のインスタンスを準備
            _browser = new System.Windows.Forms.WebBrowser();
            wfHost.Child = _browser;
            // ドキュメント読み込み終了イベントを登録.Navigatedイベント発生時は,ドキュメント読み込みが完了してないかもしれない,らしい.
            _browser.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(_browser_DocumentCompleted);
        }
        void _browser_DocumentCompleted(object sender, System.Windows.Forms.WebBrowserDocumentCompletedEventArgs e)
        {
            WinForms.HtmlDocument doc = _browser.Document as WinForms.HtmlDocument;
            //ドキュメントをいじるコードをここに書く
        }
  }
}

こんなコードを書くのは,いずれIEがすべてWPFで書き直されるまでの暫定処置だとは思いますが.