C# WebBrowser - такой простой и такой сложный. Часть 1: HTML Editor

суббота, 26 июня 2010, Александр Краковецкий

Элемент управления WebBrowser очень часто является хорошим вариантом для решения задач, связанных с Web Mining, отображением и работе с HTML данными. Несмотря на кажущуюся простоту работы с этим элементом управления, существует много проблем. На форумах очень часто можно встретить вопросы по работе с WebBrowser, на некоторые из наиболее часто задаваемых попробую ответить, а также расскажу о других приемах / трюках, с которыми пришлось столкнуться.

Работаем с WebBrowser в Windows Forms приложениях

Создадим Windows Forms приложение, в которое добавим для начала элементы управления WebBrowser, Button и RichTextbox. Первое, что сделаем - это загрузим какую-нибудь веб-страницу по умолчанию при запуске приложения. Для этого в методе Form1_Load напишем:

private void Form1_Load(object sender, EventArgs e)
{
    webBrowser.Navigate("http://m.bing.com/");
}

После чего получим такой результат:

Шаблон проекта создан, приступим к выполнению некоторых задач.

Создание HTML Editor

Мы все привыкли к онлайн-редакторам HTML, но если нам необходимо сделать это в Windows Forms приложении? WebBroser может нам помочь в этом.

В первую очередь мы должны добавить в проект ссылку на Microsoft.mshtml, после чего перепишем наш код таким образом:

        private void Form1_Load(object sender, EventArgs e)
        {
            InitWebBrowser();
        }

        private void InitWebBrowser()
        {
            string Encoding = "ISO-8859-1";
            HtmlDocument hd;
            mshtml.IHTMLDocument2 axObj;

            webBrowser.DocumentText = "";
            webBrowser.Document.Encoding = Encoding;
            hd = webBrowser.Document;
            axObj = hd.DomDocument as mshtml.IHTMLDocument2;
            axObj.designMode = "On";
            webBrowser.Navigate("http://m.bing.com/");
        }

C виду он кажется очень простым, но на самом деле каждая строчка здесь имеет большое значение (когда пришлось долго попотеть, чтобы заставить этот код работать). Сначала мы создаем переменные типа mshtml.IHTMLDocument2 и HtmlDocument. Дальше присваиваем свойству DocumentText пустое значение - если мы этого не сделаем, то на следующей строчке мы получим исключение NullReferenceException и сообщением "В экземпляре объекта не задана ссылка на объект". На самом деле, мы не можем работать с свойством webBrowser.Document до того, как оно не проинициализируется. Самый простой способ - присвоить пустую строку свойству DocumentText или написать что-то типа webDrowser.Navigate("about:blank").

Нужно еще заметить, что многие свойства WebBrowser являются COM объектами, т.е. по сути WebBrowser - это обвертка (wrapper) над более старым элементом управления AxSHDocVw.AxWebBrowser. Поэтому следующим этапом является приведение hd.DomElement к интерфейсу mshtml.IHTMLDocument2. дальше мы добрались до самой сути - изменение режима браузера  с помощью строки axObj.designMode = "On";

После этого наша страница будет редактируемой (добавим строку "Welcome from WebBrowser Demo!"):

Рассмотрим как можно менять стили в нашем HTML Editor.

Расширяем функционал HTML Editor

Понятно, что в таком виде наш редактор никому не нужен, поэтому добавим ему немного функционала.

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

Рассмотрим синтаксис метода execCommand, который принимает на вход три аргумента:

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

Из этих трех аргументов обязательным является только первый. Пример:

doc.execCommand("foreColor", false, "#FF0000");

Список команд:

Команда Описание
2D-Position Команда, позволяющая пользователю передвигать абсолютно позиционированные элементы.
AbsolutePosition Команда, устанавливающая свойство position данного элемента в значение "absolute".
BackColor Команда, устанавливающая или возвращающая цвет фона данного выделеного текста.
BlockDirLTR Не поддерживается.
BlockDirRTL Не поддерживается.
Bold Команда, переключающая состояние шрифта выделенного фрагмента текста между жирным и нормальным.
BrowseMode Не поддерживается.
Copy Команда, помещающая копию данного выделенного фрагмента текста в буфер обмена.
CreateBookmark Команда, создающая "якорь" из выделенного фрагмента текста или возвращает имя "якоря" для выделенного фрагмента текста.
CreateLink Команда, создающая гиперссылку из выделенного фрагмента текста.
Cut Команда, помещающая копию данного выделенного фрагмента текста в буфер обмена и удаляющая этот фрагмент из документа.
Delete Команда, удаляющая выделенный фрагмент текста.
DirLTR Не поддерживается.
DirRTL Не поддерживается.
EditMode Не поддерживается.
FontName Команда, задающая или возвращающая имя шрифта текста.
FontSize Команда, задающая или возвращающая размер шрифта текста
ForeColor Команда, задающая или возвращающая цвет текста.
FormatBlock Команда, форматирующая выделенный фрагмент текста как блок "DIV", "P" или "SPAN".
Indent Команда, увеличивающая отступ выделенного фрагмента текста.
InlineDirLTR Не поддерживается.
InlineDirRTL Не поддерживается.
InsertButton Команда, вставляющая в документ кнопку("BUTTON").
InsertFieldset Команда, вставляющая в документ группу "FIELDSET".
InsertHorizontalRule Команда, вставляющая в документ горизонтальную полосу прокрутки.
InsertIFrame Команда, вставляющая в документ "плавающий" фрейм.
InsertImage Команда, вставляющая в документ изображение.
InsertInputButton Команда, вставляющая в документ командную кнопку.
InsertInputCheckbox Команда, вставляющая в документ кнопку-"флажок".
InsertInputFileUpload Команда, вставляющая в документ элемент управления для отправки файла на сервер.
InsertInputHidden Команда, вставляющая в документ скрытое поле.
InsertInputImage Команда, вставляющая в документ изображение как элемент управления.
InsertInputPassword Команда, вставляющая в документ поле ввода пароля.
InsertInputRadio Команда, вставляющая в документ радиокнопку.
InsertInputReset Команда, вставляющая в документ кнопку сброса данных формы.
InsertInputSubmit Команда, вставляющая в документ кнопку отправки данных из формы на сервер.
InsertInputText Команда, вставляющая в документ поле ввода текста.
InsertMarquee Комманда, вставляющая в документ прокручивающийся текст.
InsertOrderedList Комманда, вставляющая в документ нумерованный список.
InsertParagraph Комманда, создающая абзац из выделенного фрагмента текста.
InsertSelectDropdown Комманда, вставляющая в документ выпадающий список.
InsertSelectListbox Комманда, вставляющая в документ список.
InsertTextArea Комманда, вставляющая в документ область редактирования текста.
InsertUnorderedList Комманда, вставляющая в документ маркированный список.
Italic Комманда, переключающая состояние шрифта выделенного фрагмента текста между наклонным и нормальным.
JustifyCenter Комманда, выравнивающая абзац, в который входит фрагмент выделенного текста, по центру.
JustifyFull Не поддерживается.
JustifyLeft Комманда, выравнивающая абзац, в который входит фрагмент выделенного текста, по левому краю.
JustifyNone Не поддерживается.
JustifyRight Комманда, выравнивающая абзац, в который входит фрагмент выделенного текста, по правому краю.
LiveResize Комманда, включающая или выключающая режим мгновенного("живого") отображения размеров или местоположения элементов страницы во время изменения размеров последней.
MultipleSelection Комманда, позволяющая или запрещающая выделение сразу нескольких элементов web-строницы.
Open Не поддерживается.
Outdent Комманда, уменьшающая отступ выделенного фрагмента текста.
OverWrite Комманда, переключающая режим ввода текста между вставкой и заменой.
Paste Комманда, заменяющая данный выделенный фрагмент текста на содержимое буфера обмена.
PlayImage Не поддерживается.
Print Комманда, открывающая диалоговое окно "Печать".
Redo Не поддерживается.
Refresh Комманда, перезагружающая данный документ с сервера.
RemoveFormat Комманда, удаляющая все тэги форматирования текста из выделенного фрагмента текста.
RemoveParaFormat Не поддерживается.
SaveAs Комманда, сохраняющая текущую web-страницу в файл.
SelectAll Комманда, выделяющая весь документ.
SizeToControl Не поддерживается.
SizeToControlHeight Не поддерживается.
SizeToControlWidth Не поддерживается.
Stop Не поддерживается.
StopImage Не поддерживается.
StrikeThrough Не поддерживается.
Subscript Не поддерживается.
Superscript Не поддерживается.
UnBookmark Комманда, удаляющая элемент закладки из текущего фрагмента выделенного текста.
Underline Комманда, устанавливающая подчёркивание для выделенного фрагмента текста или снимающая это подчёркивание.
Undo Не поддерживается.
Unlink Комманда, удаляющая элемент гиперссылки из текущего фрагмента выделенного текста.
Unselect Комманда, очищающая данный фрагмент выделенного текста.

Добавим обработчик события button1_Click и напишем:

        private void button1_Click(object sender, EventArgs e)
        {
            HtmlDocument doc = webBrowser.Document;
            doc.ExecCommand("Bold", false, null);
        }

При запуске приложения вы можете выделить произвольный текст и установить стиль шрифта жирным путем нажатия на нашу кнопку. Таким образом вы можете написать полноценный HTML Editor, который будет поддерживать все команды форматирования.

Переход на новую страницу

И тут хочется рассказать об еще одной особенности работы с веб-браузером, на которую в свое время было потрачено очень много времени. Я говорю о ситуации, когда вам необходимо перейти на другой веб-сайт или загрузить новый шаблон для редактирования. Для демонстрации этой ситуации перепишем код button1_Click так, чтобы перенаправлять браузер на другую страницу, например на http://google.com/:

        private void button1_Click(object sender, EventArgs e)
        {
            webBrowser.Navigate("http://google.com/");
        }

В случае, если мы ничего не меняли в исходном шаблоне, переход при нажатии на кнопку пройдет успешно, но если вы хоть что-то поменяли в исходном документе, то при переходе вы увидите такое окно:

Я обшарил весь интернет в поисках решения, но ответа не нашел ни на одном из ресурсов, свойства типа ShowWarningPopup нет. В итоге решение пришло в виде такого трюка:

void ChangeAllowWebBrowserDrop()
        {
            webBrowser.AllowWebBrowserDrop = !webBrowser.AllowWebBrowserDrop;
        }

Эта функция изменяла свойство веб-браузера на противоположный, ее нужно вызывать перед тем как осуществлять переход на новую страницу. Вся соль в том, что простое присвоение true или false не помогает, необходимо каждый раз менять значение свойства на противоположный!

В следующих постах рассмотрим другие особенности работы с C# WebBrowser.

Компании из статьи


Microsoft Украина


Сайт:
http://www.microsoft.com/ukr/ua/

Microsoft Украина Украинское подразделение компании Microsoft.

Ищите нас в интернетах!

Комментарии

Свежие вакансии