Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Разработка Windows Forms > Webbrowser + Ajax


Автор: Spancer 20.4.2010, 13:17
1) Собственно задача она же проблема.
Есть страница DHTML, в которую с помощью AJAX дозагружаются данные.
Событие Webbrowser.DocumentCompleted наступает когда страница полностью загружена, но динамическая часть грузится после полной загрузки основной части в контейнер <div>. Так вот, стоит вопрос каким способом можно отследить загрузку этого контейнера. Решение нашел с помощью while искать текст на странице, который загружается в этот контейнер. Но этот текст может быть различным.

2) Иногда страница выбрасывает javascript окно alert();
Как его закрыть, а еще лучше проигнорировать?

Все нужно решить на основе компонента Webbrowser.

Автор: diadiavova 20.4.2010, 14:21
По первому вопросу всё достаточно просто: надо после загрузки документа прикрутить к событию onpropertychange обработчик  в нём отслеживать изменение значения свойства innerHTML. А вот на счёт алерта не знаю, думаю простого решения нет.

Автор: Spancer 20.4.2010, 14:36
onpropertychange - таких событий я не знаю, в нём отслеживать изменение значения свойства innerHTML. каким образом?

у меня работает все так:

                        while (webBrowser1.ReadyState != WebBrowserReadyState.Complete)
                        {
                            Application.DoEvents();
                            this.Update();
                        }
                        while (webBrowser1.Document.Body.InnerText.IndexOf("Ждет какой то определенный текст, появление которого сведетельствует, что динамическая часть загружена") >= 0)
                        {
                            Application.DoEvents();
                            this.Update();
                        }

Но это все сжирает огромные ресурсы, 8 экземпляров такое программы вешают 4х ядерный проц на 100%. А хочется не ограничиваться 8 экземплярами, вообще в недалеком будущем это все будет работать в разных потоках.

Автор: diadiavova 20.4.2010, 16:17
Пример в аттаче. Там вебстраничка, с текстовым полем и кнопкой. Если в текстовое поле ввести текст и нажать кнопку, то текст загружается в div. В программе отслеживается изменение свойства innerHTML этого дива и когда оно происходит выскакивает сообщение с этим самым хтмл-кодом.

Автор: Spancer 20.4.2010, 16:46
Спасибо конечно, но что то пример не работает

Автор: diadiavova 20.4.2010, 16:48
Это скорей всего из-за библиотеки mshtml, просто убери её из списка ссылок и добавь заново стандартными средствами студии.

Автор: Spancer 21.4.2010, 09:49
После добавление библиотеки ни чего не изменилось, думаю потому что по умолчанию контейнер <div> уже не пустой.
Поясните строку:
Код

if (((IHTMLEventObj2)(pEvtObj)).propertyName == "InnerHtml";

Автор: diadiavova 21.4.2010, 10:04
Цитата(Spancer @  21.4.2010,  10:49 Найти цитируемый пост)
После добавление библиотеки ни чего не изменилось

Не знаю, у меня всё работает.
Цитата(Spancer @  21.4.2010,  10:49 Найти цитируемый пост)
Поясните строку:

Эта строка должна выглядеть так
Код

if (((mshtml.IHTMLEventObj2)(pEvtObj)).propertyName == "innerHTML")
И в моём проекте она такой и была. 
Аргшумент приводится от одного типа интерфейса к другому и его свойство propertyName сравнивается со строкой "innerHTML". Событие onpropertychange возникает при изменении любого свойства, имя изменившегося свойства как раз и возвращает propertyName. Поскольку надо отслеживать свойство innerHTML, проводится именно такая проверка.

Добавлено через 3 минуты и 5 секунд
Цитата(Spancer @  21.4.2010,  10:49 Найти цитируемый пост)
 думаю потому что по умолчанию контейнер <div> уже не пустой

Это не имеет значения. Событие срабатывает каждый раз при изменении содержимого дива.

Автор: Spancer 21.4.2010, 12:33
Вообщем ни чего не заработало, как бы я не пробывал, ОС: Windows XP Prof SP3, Windows Server R2, Visual Studio 2008 prof

Автор: diadiavova 21.4.2010, 13:42
Цитата(Spancer @  21.4.2010,  13:33 Найти цитируемый пост)
ОС: Windows XP Prof SP3, Windows Server R2, Visual Studio 2008 prof 

По идее от оси это не должно зависеть. Тут надо следующие вопросы рассмотреть
1. Изменял ли ты код прежде чем запустить? В том варианте, что ты приводил, ты изменил регистр символов, в таком виде сработать и не должно. Если менял что-то ещё, просто распакуй архив снова и запусти как есть.
2.Выдаёт ли студия какие-нибуд предупреждения? Если нет ошибок, это не значит, что всё правильно, при отсутствии ошибок проект может скомпилиться и не работать, так что обрати внимание и на предупреждения тоже.
3. Если не поможет - создай новый проект, добавь в него библиотеку mshtml, кинь на форму браузер и скопируй код. Так же перетяни туда вебстраничку и в свойствах укажи, чтобы она копировалась в программу. Иными словами собери проект заново.

Автор: Spancer 21.4.2010, 14:30
Цитата(diadiavova @ 21.4.2010,  13:42)
Цитата(Spancer @  21.4.2010,  13:33 Найти цитируемый пост)
ОС: Windows XP Prof SP3, Windows Server R2, Visual Studio 2008 prof 

По идее от оси это не должно зависеть. Тут надо следующие вопросы рассмотреть
1. Изменял ли ты код прежде чем запустить? В том варианте, что ты приводил, ты изменил регистр символов, в таком виде сработать и не должно. Если менял что-то ещё, просто распакуй архив снова и запусти как есть.
2.Выдаёт ли студия какие-нибуд предупреждения? Если нет ошибок, это не значит, что всё правильно, при отсутствии ошибок проект может скомпилиться и не работать, так что обрати внимание и на предупреждения тоже.
3. Если не поможет - создай новый проект, добавь в него библиотеку mshtml, кинь на форму браузер и скопируй код. Так же перетяни туда вебстраничку и в свойствах укажи, чтобы она копировалась в программу. Иными словами собери проект заново.

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

Код

        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            div1 = webBrowser1.Document.GetElementById("main_container");
            EventHandler eh = new EventHandler(AjaxContainerLoadData);
            div1.AttachEventHandler("onpropertychange", eh);
        }

        void AjaxContainerLoadData(object sender, EventArgs e)
        {
            MessageBox.Show("123");
        }

Осталось только решить вопрос с JavaScript alert().

Автор: diadiavova 21.4.2010, 17:34
Цитата(Spancer @  21.4.2010,  15:30 Найти цитируемый пост)
сам решил проблему следующим способом:

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

Автор: Spancer 22.4.2010, 05:41
Согласен, но другого решения я пока не нашел, а мне это критично :(

Добавлено @ 05:50
2) тоже решено, но эротика полная.

        public const int WM_SYSCOMMAND = 0x0112;
        public const int SC_CLOSE = 0xF060;

        [DllImport("user32.dll")]
        public static extern int FindWindow(
            string lpClassName,
            string lpWindowName
        );

        [DllImport("user32.dll")]
        public static extern int SendMessage(
            int hWnd,
            uint Msg, 
            int wParam, 
            int lParam
        ); 

        private void timer1_Tick(object sender, EventArgs e)
        {
            int iHandle = FindWindow(null, "Сообщение с веб-страницы");
            SendMessage(iHandle, WM_SYSCOMMAND, SC_CLOSE, 0);
        }

Автор: diadiavova 22.4.2010, 09:04
Цитата(Spancer @  22.4.2010,  06:41 Найти цитируемый пост)
Согласен, но другого решения я пока не нашел, а мне это критично :(

А что у тебя происходит с моим примером? Ты ничего не написал как он работает, запускается ли вообще, выдаёт ли придупреждения и так далее.

Я переписал проект под второй фреймворк, внёс незначительные изменения(ничего принципиального, просто так понятнее), попробуй запустить. Ну вообще всё это очень странно.

Автор: Spancer 22.4.2010, 15:36
Он запускается, ни каких эксепшинов нет, просто как минибраузер со страницей и кнопкой хтмл с добавлением текста в див контейнер.
И да, мой способ тоже работает некорректно:
То есть, если:
div.InnerHtml = "1";

евент сработает если div.InnerHtml = "что то отличное от 1", НО как только div.InnerHtml опять примет значение = "1" или другому значению которое он уже принимал, то евент не происходит. Грубо говоря он хранит ВСЕ значения которые принимал за время работы программы и евент происходит только тогда когда div.InnerHtml принимает значение отличное от всех предидущих, а мне надо чтобы он мог принимать и одно и тоже значение и эвент срабатывал.

То: diadiavova

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

Автор: Spancer 22.4.2010, 15:56
Да, второй проект заработал, теперь месаджбокс выскакивает когда вбиваешь текст, сейчас в своем проекте попробую.

Автор: diadiavova 22.4.2010, 19:07
Цитата(Spancer @  22.4.2010,  16:56 Найти цитируемый пост)
Да, второй проект заработал

Видимо у тебя просто что-то не установлено на компе, что в моём первом примере присутствует(например sp1 для фреймворка), а я, создавая проект, не придал этому значения.
Цитата(Spancer @  22.4.2010,  16:36 Найти цитируемый пост)
 Грубо говоря он хранит ВСЕ значения которые принимал за время работы программы 

Попробуй отслеживать изменение свойства innerText

Автор: Spancer 22.4.2010, 20:15
Да в моей реализации это не возможно, он не ослеживает изменение какого то определеного свойства как например инерхтмл или инетекст, реагирует на изменения любого пропертиса :(

Про СП1 ни чего не могу сказать, у меня установлена ВС2008 на Виндоус Сервер 2008 Р2, ни чего кроме, фрейворк 3.5 отдельно инсталится не хочет

Добавлено через 9 минут и 28 секунд
видимо разобрался из за чего первый проект не работал, я подключал другую версию mshtnl.dll из другого каталога, вручную, а не стандартную из списка.

Автор: Spancer 22.4.2010, 21:21
Мда, протестировал на своем проекте, код рабочий, но не для моего случая, в моем случае меняются различные свойства элемента див, в евенте, кроме innerHTML. хотя содержимое тега меняется. :( бред

Автор: diadiavova 22.4.2010, 21:25
Цитата(Spancer @  22.4.2010,  22:21 Найти цитируемый пост)
 в моем случае меняются различные свойства элемента див, в евенте, кроме innerHTML

Ну дык отслеживай все свойства. Просто вусловии укажи список нужных свойств и всё. Какие с этим проблемы то? smile

Добавлено через 3 минуты и 30 секунд
А вообще тут ещё вся штука в том, что вроде происходит одно и то же, а событй может произойти несклько. Например если меняется текстовое содержимое, то будут изменяться как минимум 2 свойства: innerText и innerHTML, кроме того елемент очевидно изменится в размерах итд, так что лучше всё-таки отслеживать именно то свойство, изменение которого тебя интересует.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)