Событие WebBrowser OnPropertyChange не запускается

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

Следующий код — моя попытка решить эту проблему, но безуспешно.

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    HtmlElement div_result = webBrowser1.Document.GetElementById("div_result");
    div_result.AttachEventHandler("onpropertychange", new EventHandler(resultEventHandler));
}
private void resultEventHandler(object sender, EventArgs e)
{
    MessageBox.Show("Loaded");
}

Если я нажму кнопку ввода, содержимое div будет изменено, но resultEventHandler не сработает.

Итак, у меня есть два вопроса:

  1. Где моя ошибка в этом коде?
  2. Есть ли «обычный способ» (я имею в виду без использования таймеров или Aplication.DoEvents()) для работы с ajax с использованием элемента управления WebBrowser в С#?

person zerocube    schedule 23.12.2012    source источник
comment
Это потому, что изменение innerText или innerHTML дочерних элементов не приведет к срабатыванию события onpropertychange для родительского элемента? Потому что при изменении содержимого никакие свойства DIV не должны изменяться. msdn.microsoft.com/en-us /library/ie/ms536956(v=vs.85).aspx   -  person aliassce    schedule 25.06.2014


Ответы (3)


Изменение innerText или innerHTML дочерних элементов не приведет к срабатыванию события onpropertychange для родительского элемента.

person HMarioD    schedule 24.12.2012
comment
Я прочитал эту заметку из msdn, но у меня нет дочерних элементов. У меня есть очень простая веб-страница , которую я сделал специально для этого эксперимента. - person zerocube; 24.12.2012

Я не могу сказать, почему у вас не работают события HtmlElement. Но у меня была та же проблема, и я решил ее с помощью оболочек COM:

mshtml.HTMLDocumentClass doc = (mshtml.HTMLDocumentClass)webBrowser1.Document.DomDocument;
mshtml.IHTMLElement2 div_result = (mshtml.IHTMLElement2)doc.getElementById("div_result");
mshtml.HTMLElementEvents2_Event events = (mshtml.HTMLElementEvents2_Event)div_result;
events.onpropertychange += resultEventHandler;
person Paul B.    schedule 25.06.2014

Это может быть слишком поздно, но вот это в любом случае, если вы все еще задаетесь вопросом:

1 - HtmlElement div_result = webBrowser1.Document.GetElementById("div_result"); Строка № 1 выполняется, когда веб-страница загружается и событие DocumentCompleted вызывается браузером. Внутри обработчика событий вы сначала получаете указатель на элемент DOM «div_result» и назначаете переменную типа HtmlElement с именем div_result.

2 - div_result.AttachEventHandler("onpropertychange", новый EventHandler(resultEventHandler)); Строка №2 — регистрирует событие onpropertychange и назначает метод resultEventHandler в качестве метода слушателя.

Каждый раз, когда вы нажимаете кнопку на своей веб-странице, кнопка (как я предполагаю) находится в форме, которая отправляется, что вызывает загрузку веб-страницы; кстати, вы не указали, какой метод публикации вы используете при нажатии кнопки (получить или опубликовать). Когда загрузка веб-страницы завершается и дерево элементов DOM построено, вызывается событие DocumentCompleted. Вы метод обработчика события DocumentCompleted выполнил инструкции, описанные выше.

Каждый раз, когда вы нажимаете кнопку, ваша веб-страница перезагружается, и вы переназначаете прослушиватель событий для события onpropertychange. Вы только назначаете прослушиватель событий. Событие никогда не будет вызвано. Он будет просто определяться каждый раз, когда вы нажимаете кнопку. У вас есть классическая проблема, что было раньше: курица или яйцо. Но в вашем случае ваш цыпленок - это событие нажатия кнопки, вызывающее запуск метода DocumentCompleted, который сбрасывает состояние всех переменных в методе, и вашему яйцу требуется указатель на событие onpropertychange элемента DIV до того, как кнопка будет нажата в Интернете страница . Как вы назначаете прослушиватель событий для htmlelement, прежде чем вы сможете получить указатель из DOM, который не был создан? Поместите переменную логического флага в класс, содержащий метод DocumentCompleted, и установите его начальное состояние. Переместите переменную div_result за пределы метода DocumentCompleted, чтобы увеличить ее область действия и сохранить ее состояние в случае нажатия кнопки. Таким образом, вы получите указатель на свой элемент div и установите его прослушиватель событий onpropertychange при первой загрузке веб-страницы. Добавьте тест, если вы просто хотите установить указатель на прослушиватель событий onpropertychange элемента DIV только один раз (я поместил его в приведенный ниже пример кода), и при следующем нажатии кнопки ваше событие сработает. ПРИМЕЧАНИЕ! Убедитесь, что вы не добавляете и не удаляете какой-либо элемент на своей веб-странице после сохранения указателя на любой из элементов веб-страницы или их событий. В противном случае вам придется повторно анализировать DOM, чтобы получить указатель на новую позицию элемента в дереве DOM.

//Увидеть ниже:

class SomeClass
{
    bool DocumentHasLoaded = false;
    HtmlElement div_result = null;

    //Constructor and other methods go here....

    //Then change your DocumentCompleted method to look like this:
    private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {

        if (DocumentHasLoaded == false)  // I prefer using a ! before the variable instead
        {
            DocumentHasLoaded = true;    // You will have to create your own appropriately timed mechanism to reset this variable's state should you want to execute the whole process again.
            div_result = webBrowser1.Document.GetElementById("div_result");
            div_result.AttachEventHandler("onpropertychange", new EventHandler(resultEventHandler));
        }
    }
}

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

person Jamie    schedule 30.09.2014
comment
Я предпочитаю использовать ! перед переменной, так зачем делать что-то еще? - это твой ответ - person weston; 13.01.2015
comment
Этот анализ имеет смысл, если нажатие кнопки вызывает обновление страницы. Но если нажатие кнопки запускает некоторый (на стороне клиента) javascript со страницы, где этот JS изменяет элемент div_result, то должен запускаться обработчик события C# для onpropertychange, не так ли? FWIW У меня есть аналогичный случай, когда раньше вызывался обработчик событий C #, но теперь этого не происходит. В настоящее время я подозреваю изменение поведения в MSIE из-за обновления Windows. См. также - person shaun; 14.12.2020