如何将HTML加载到WPF的Webbrowser控件中?

时间:2010-12-08 18:53:16

标签: c# .net wpf webbrowser-control

我的WPF客户端应用程序正在构建一个自定义HTML页面,我可以像这样加载HTML,

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

我遇到的问题是如果HTML中有图像和css文件,我如何将自定义HTML加载到Webbrowser控件中?

你如何引用图像和CSS?可以将图像和CSS嵌入到应用程序中,还是需要将它们放在某个目录中?

感谢您的帮助。

5 个答案:

答案 0 :(得分:4)

实际上,有一个带嵌入图像的HTML页面。

您可以使用data URI scheme将图像和CSS嵌入HTML字符串中。但是,并非所有版本的IE都支持此功能,而WebBrowser控件实际上就是IE。如果您的代码可能在IE&lt; 8,这种方法对你没有帮助。

另一个选择是将图像和CSS存储为嵌入资源,将它们写入临时文件,然后在生成HTML时将绝对URL插入临时文件。

答案 1 :(得分:1)

由于您正在生成HTML,因此您可以通过生成指向您可以控制的某个地方的base element来设置所有脚本/图像的基本网址,例如指向文件夹的文件:/// url磁盘,指向本地Web服务器正在侦听的localhost的URL(因特网上有太多的http服务器示例,所以我不在这里详细介绍),或者是您在www上的网站。

当您导航到字符串时,HTML将在与about:blank相同的interenet区域中呈现。根据客户端的IE安全区域设置,您的HTML可能没有权限在某些位置加载文件(如果页面位于Internet区域中,则计算机上的脚本文件)。

您可以使用Mark of the Web更改HTML网页的互联网区域。

答案 2 :(得分: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());

答案 3 :(得分:0)

您可以像对待其他每个HTML页面一样完成此操作。图像和CSS将由URL引用,就像任何其他HTML页面一样。这里没有魔力。

答案 4 :(得分:0)

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