2010-12-08 5 views
9

Мои WPF клиентское приложение строит пользовательский HTML страницу, я могу загрузить HTML, как это,Как загрузить HTML в элемент управления Webbrowser для WPF?

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

Проблема у меня есть, как я могу загрузить пользовательский HTML в элемент управления Webbrowser, если HTML есть изображения и css файл в нем?

Как вы ссылаетесь на изображения и css? Могут ли изображения и css быть встроены в приложение, или они должны быть где-то в каталоге?

Спасибо за помощь.

ответ

0

Вы бы сделали это точно так же, как и с любой другой HTML-страницей. Изображения и CSS будут ссылаться по URL-адресу, как на любой другой HTML-странице. Здесь нет никакой магии.

+0

Мое приложение генерирует HTML, оно не существует на URL-адресе. – Tony 2010-12-08 19:00:07

+1

Но, как и любая другая HTML-страница в мире, любые изображения или CSS должны быть указаны по URL-адресу. Нет такой вещи, как HTML-страница со встроенными изображениями. – 2010-12-08 19:01:39

+0

Да, наверное. Вы все это продумали? Может быть, пришло время остановиться и прочитать учебник по HTML? – 2010-12-08 19:08:37

4

На самом деле, есть такая вещь, как HTML-страница со встроенными изображениями.

Вы можете вставлять оба изображения и CSS внутри строки HTML, используя data URI scheme. Однако не все версии IE поддерживают это, а элемент управления WebBrowser - это IE. Если ваш код может работать на компьютере с IE < 8, этот подход вам не поможет.

Другим вариантом является сохранение изображений и CSS в качестве встроенных ресурсов, их запись в временные файлы, а затем вставка абсолютных URL-адресов в временные файлы при создании HTML-кода.

1

Поскольку вы генерируете HTML-код, вы можете установить базовый url всего сценария/образа, создав base element, который указывает на то, где вы управляете, например файл: /// url, указывающий на папку на диске, url, указывающий на localhost, где ваш локальный веб-сервер прослушивает (слишком много образцов HTTP-сервера в Интернете, поэтому я не вдаваюсь в подробности здесь) или ваш веб-сайт на www.

Когда вы переходите к строке, HTML будет отображаться в одной и той же зоне межсетевого пространства: около. В зависимости от настроек зоны безопасности IE клиента ваш HTML может не иметь разрешения на загрузку файлов в определенных местах (например, файлы сценариев на компьютере, если страница находится в зоне Интернета).

Вы можете использовать Mark of the Web, чтобы изменить интернет-зону своей HTML-страницы.

1

Для справки я наткнулся на этот вопрос и использовал ответ Джоэла Мюллера, но решил автоматизировать синтаксический анализ путей изображения. Может быть, кто-то найдет мой код полезным для стартера аналогичного решения - он довольно грубый и грязный, но, похоже, хорошо справляется с этой задачей.

Я использую ресурсы C#, внутри своих html-файлов я помещаю только имена файлов изображений. Он также позволяет мне открыть файл в обычном браузере для тестирования того, как он будет выглядеть. Код автоматически ищет ресурс с тем же именем, что и имя файла внутри html, сохраняет его в каталоге данных приложения и заменяет путь.

Следует также отметить, что приложение будет перезаписывать файл, если он отличается от уже сохраненного. В основном это было необходимо для разработки, но на самом деле у меня не было много таких файлов, поэтому здесь меня не волновало потеря производительности. Опуская эту проверку и предполагая, что файлы обновлены, необходимо повысить производительность.

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"); 
Смежные вопросы