2010-12-08 11 views
9

私のWPFのクライアントアプリケーションがカスタムHTMLページを構築して、私はこのようなHTMLを読み込むことができ、WPFのWebブラウザーコントロールにHTMLを読み込むにはどうすればよいですか?

this.myWebBrowser.NavigateToString("<html><body><p>test page</p></body></html>"); 

私が持っている問題は、HTML、画像を持っているとあれば、私は、WebBrowserコントロールにカスタムHTMLをロードしない方法ですそれにCSSファイル?

どのように画像とCSSを参照していますか?画像やCSSをアプリケーションに埋め込むことができますか、どこかのディレクトリに置く必要がありますか?

ありがとうございました。

答えて

0

これは他のすべてのHTMLページとまったく同じように行います。画像とCSSは他のHTMLページと同様にURLで参照されます。ここには魔法はありません。

+0

私のアプリケーションはHTMLを生成していますが、URLには存在しません。 – Tony

+1

しかし、世界中の他のすべてのHTMLページと同様、URLを介して画像やCSSを参照する必要があります。画像が埋め込まれたHTMLページはありません。 –

+0

はい、そうですね。あなたはこれを何とか思ったのですか?多分、HTMLに関するチュートリアルをやめて読んでみようか? –

4

実際には、画像が埋め込まれたHTMLページなどがあります。

画像とCSSの両方をdata URI schemeを使用してHTML文字列に埋め込むことができます。しかし、IEのすべてのバージョンがこれをサポートしているわけではなく、WebBrowserコントロールは本当にIEです。コードがIE < 8のマシンで実行される場合、この方法は役に立ちません。

イメージやCSSを埋め込みリソースとして保存し、一時ファイルに書き出し、HTMLを生成するときに絶対URLを一時ファイルに挿入することもできます。

+0

私は埋め込みを試み、うまくいった。 – Tony

+0

webbrowserコントロールは常にローカルIEを使用しますか?それとも、PCにie6しかない場合でも、常に動作するようにアプリケーションにコンパイルされますか? – Tony

+0

私はそれが常にローカルIEを使用すると確信しています。そうしないと、複数のバージョンのIEをテスト用の単一のマシンにインストールする方が簡単です。 –

1

HTMLを生成しているので、ディスク上のフォルダを指し示しているfile:/// urlのように、制御できる場所を指すbase elementを生成することで、すべてのスクリプト/画像のベースURLを設定できます。あなたのローカルWebサーバーがリッスンしているlocalhostを指しているURL(インターネット上のあまりにも多くのhttpサーバーのサンプルがあるので、ここで詳しく説明しません)、またはwwwのWebサイト。

stringに移動すると、HTMLはabout:blankと同じinterenetゾーンにレンダリングされます。クライアントのIEセキュリティゾーンの設定によっては、HTMLが特定の場所(インターネットゾーンにある場合はコンピュータ上のスクリプトファイルなど)にファイルを読み込む権限がない場合があります。

Mark of the Webを使用して、HTMLページのインターネットゾーンを変更することができます。

1

参考までに、私はこの質問に遭遇し、Joel Muellerの答えを使用しましたが、画像パスの解析を自動化することに決めました。たぶん誰かが、私のコードが似たような解決策のスターターにとって有益だと思うかもしれません。それはかなり荒く汚れていますが、うまくやっているようです。

私はC#リソースを使用しています。私のhtmlファイルの中には、イメージファイル名のみを入れています。また、通常のブラウザでファイルを開いて、どのように見えるかをテストすることもできます。コードは自動的にhtml内のfilenameと同じ名前のリソースを探し、アプリケーションデータディレクトリの下に保存してパスを置き換えます。

既に保存されているファイルと異なる場合は、アプリケーションがファイルを上書きすることにも注意してください。開発には主に必要でしたが、実際にはそれらのファイルがほとんどなかったため、ここでのパフォーマンスの低下は気にしませんでした。このチェックを省略し、ファイルが最新であると仮定すると、パフォーマンスが向上するはずです。

Settings.Default.ApplicationIdは、アプリケーション名の単純な文字列で、アプリケーションデータ内のディレクトリ名に使用されます。私のクラスは見終わった方法です

class MyHtmlImageEmbedder 
    { 
     static protected string _appDataDirectory = 
      Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), 
       Settings.Default.ApplicationId); 

     static public string getHtml() 
     { 
      String apiHelp = Resources.html_file; 
      Regex regex = new Regex(@"src=\""(.*)\""", RegexOptions.IgnoreCase); 
      MatchCollection mc = regex.Matches(apiHelp); 
      foreach (Match m in mc) 
      { 
       string filename = m.Groups[1].Value; 
       Image image = Resources.ResourceManager.GetObject(Path.GetFileNameWithoutExtension(filename)) as Image; 
       if (image != null) 
       { 
        var path = getPathTo(Path.GetFileNameWithoutExtension(filename) + ".png", imageToPngByteArray(image)); 
        apiHelp = apiHelp.Replace(filename, path); 
       } 
      } 
      return apiHelp; 
     } 

     static public string getPathTo(string filename, byte[] contentBytes) 
     { 
      Directory.CreateDirectory(_appDataDirectory); 
      var path = Path.Combine(_appDataDirectory, filename); 
      if (!File.Exists(path) || !byteArrayCompare(contentBytes, File.ReadAllBytes(path))) 
      { 
       File.WriteAllBytes(path, contentBytes); 
      } 
      return path; 
     } 

     [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)] 
     static extern int memcmp(byte[] b1, byte[] b2, long count); 

     public static bool byteArrayCompare(byte[] b1, byte[] b2) 
     { 
      // Validate buffers are the same length. 
      // This also ensures that the count does not exceed the length of either buffer. 
      return b1.Length == b2.Length && memcmp(b1, b2, b1.Length) == 0; 
     } 

     public static byte[] imageToPngByteArray(Image image) 
     { 
      MemoryStream ms = new MemoryStream(); 
      image.Save(ms, System.Drawing.Imaging.ImageFormat.Png); 
      return ms.ToArray(); 
     } 
    } 

はbyteArrayCompareFunctionが唯一のパフォーマンス上の理由からmemcmpを使用していますが、それは簡単な比較ループで置換することができることに注意してください。

次に、私はbrowser.NavigateToString(MyHtmlImageEmbedder.getHtml());に電話しています。

0
<WebBrowser Height="200" Name="myWebBrowser"></WebBrowser> 
myWebBrowser.NavigateToString("EnterHtmlString"); 
+0

これはどのようにして質問に答えますか?彼はすでに 'NavigateToString'を使用しています。私は、" EnterHtmlString "を渡すことでCSSと画像ファイルの問題が解決するのではないかと疑います。 – Stephan

関連する問題