Как загрузить HTML в элемент управления Webbrowser для WPF? - PullRequest
9 голосов
/ 08 декабря 2010

Мое клиентское приложение WPF создает пользовательскую страницу HTML, я могу загрузить HTML следующим образом,

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

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

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

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

Ответы [ 5 ]

4 голосов
/ 09 декабря 2010

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

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

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

1 голос
/ 16 сентября 2013

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

Я использую ресурсы 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());.

1 голос
/ 15 декабря 2010

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

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

Вы можете использовать Метку Интернета , чтобы изменить интернет-зону HTML-страницы.

0 голосов
/ 12 ноября 2015
<WebBrowser Height="200" Name="myWebBrowser"></WebBrowser>
myWebBrowser.NavigateToString("EnterHtmlString");
0 голосов
/ 08 декабря 2010

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

...