我的WPF客户端应用程序正在构建一个自定义HTML页面,我可以像这样加载HTML,
this.myWebBrowser.NavigateToString("<html><body><p>test page</p></body></html>");
我遇到的问题是如果HTML中有图像和css文件,我如何将自定义HTML加载到Webbrowser控件中?
你如何引用图像和CSS?可以将图像和CSS嵌入到应用程序中,还是需要将它们放在某个目录中?
感谢您的帮助。
答案 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");