Я должен быть еретиком для того, чтобы хотеть браузер C # с NewWindow2 и GetElementsByTagName - PullRequest
0 голосов
/ 21 марта 2012

Вы не можете получить свой торт и съесть его, по-видимому.

В настоящее время я использую System.Windows.Forms.WebBrowser в своем приложении.В настоящее время программа зависит от использования функции GetElementsByTagName.Я использую его, чтобы собрать все элементы определенного типа (либо «входные», либо «текстовые»), чтобы я мог отсортировать их и вернуть значение определенного элемента.Вот код этой функции (мой веб-браузер называется web1):

// returns the value from a element.
public String FetchValue(String strTagType, String strName) 
{
    HtmlElementCollection elems;
    HtmlDocument page = web1.Document.Window.Frames[1].Document;
    elems = page.GetElementsByTagName(strTagType);
    foreach (HtmlElement elem in elems)
    {
        if (elem.GetAttribute("name") == strName ||
            elem.GetAttribute("ref") == strName)
        {
            if (elem.GetAttribute("value") != null)
            {
                return elem.GetAttribute("value");
            }
        }
    }

    return null;
}

(указывает на то, что веб-страница, из которой мне нужно извлечь, находится во фрейме, и, в зависимости от обстоятельств, идентифицирующее имя элементабудет либо в названии, либо в атрибуте ref)

Все это работает как сон с System.Windows.Forms.WebBrowser.

Но то, что он не может сделать, - это перенаправить открытиеновое окно, чтобы остаться в приложении.Все, что открывается в новом окне, запускается в браузере пользователя по умолчанию, тем самым теряя сеанс.Эту функциональность можно легко исправить с помощью события NewWindow2, которого System.Windows.Forms.WebBrowser не имеет.

Теперь простите за то, что я ошеломлен его отсутствием.Я только что отказался от VB6 и перешел на C # (да, VB6, очевидно, я работаю под скалой), а в VB6 WebBrowser обладал как функцией GetElementsByTagName, так и событием NewWindow2.

У AxSHDocVw.WebBrowser есть событие NewWindow2.Я был бы более чем рад помочь мне направить мои новые окна туда, где они мне нужны.Код для этого в THAT WebBrowser: (frmNewWindow - простая форма, содержащая только другую WebBrowser, называемую web2 (Dock установлена ​​в Fill)):

private void web1_NewWindow2(
                      object sender, 
                      AxSHDocVw.DWebBrowserEvents2_NewWindow2Event e)
{
    frmNewWindow frmNW = new frmNewWindow();
    e.ppDisp = frmNW.web2.Application;
    frmNW.web2.RegisterAsBrowser = true;
    frmNW.Visible = true;
}

Я не могу произвести самостоятельноспособ воспроизвести эту функцию с подавляющим регулярным событием NewWindow.

Я также не могу понять, как воспроизвести функцию FetchValue, описанную выше, используя AxSHDocVw.WebBrowser.Кажется, все идет совсем по-другому, и все мои знания о том, как делать вещи, бесполезны.

Я знаю, что я больной, извращенный человек из-за этой странной фантазии об использовании этих двух вещей водно приложение.Но можете ли вы найти в своем сердце помощь этому глупому идеалисту?

Ответы [ 3 ]

2 голосов
/ 31 марта 2012

Я больше не мог полагаться на обходной путь, и мне пришлось отказаться от System.Windows.Forms.WebBrowser.Мне нужен NewWindow2.

В конце концов я понял, как выполнить то, что мне нужно, с помощью AxWebBrowser.В моем первоначальном посте было запрошено либо решение для NewWindow2 в System.Windows.Forms.WebBrowser, либо замена AxWebBrowser для .GetElementsByTagName.Замена требует примерно в 4 раза больше кода, но выполняет свою работу.Я думал, что было бы разумно опубликовать мое решение, для более поздних Googlers с тем же затруднением.(также в случае, если есть лучший способ сделать это)

IHTMLDocument2 webpage = (IHTMLDocument2)webbrowser.Document;
IHTMLFramesCollection2 allframes = webpage.frames;
IHTMLWindow2 targetframe = (IHTMLWindow2)allframes.item("name of target frame");
webpage = (IHTMLDocument2)targetframe.document;
IHTMLElementCollection elements = webpage.all.tags("target tagtype");

foreach (IHTMLElement element in elements)
{
  if (elem.getAttribute("name") == strTargetElementName)
   {
     return element.getAttribute("value");
   }
}

Webbrowser.Document преобразуется в IHTMLDocument2, затем кадры IHTMLDocument2 помещаются в IHTMLFramesCollection2, затем я преобразую конкретный нужный кадр вIHTMLWindow2 (вы можете выбрать кадр по индексу # или имени), затем я преобразую элемент фрейма .Document в IHTMLDocument2 (изначально использовавшийся для удобства).Оттуда, метод .all.tags () IHTMLDocument2 функционально идентичен старому методу WebBrowser.Document.GetElementsByTagName (), за исключением того, что для него требуется IHTMLElementCollection вместо HTMLElementCollection.Затем вы можете просмотреть коллекцию, отдельные элементы которой должны быть IHTMLElement, и использовать .getAttribute для получения атрибутов.Обратите внимание, что строчная буква g.

0 голосов
/ 21 марта 2012

Единственное решение этой проблемы, которое я видел, было несколько лет назад под названием csExWb2, теперь в коде Google здесь .

Он предоставляет вам элемент управления ExWebBrowser, но с полным доступом ко всем интерфейсам и событиям, предлагаемым IE. Я использовал его, чтобы получить глубокий и грязный контроль над элементами в размещенном в Winforms HTML-редакторе.

Это может быть что-то вроде прыжка, прыгнув прямо в это, ум.

0 голосов
/ 21 марта 2012

Элемент управления WebBrowser может обрабатывать событие NewWindow, поэтому в WebBrowser будут открываться новые всплывающие окна.

private void webBrowser1_NewWindow(object sender, CancelEventArgs e)
{
  // navigate current window to the url
  webBrowser1.Navigate(webBrowser1.StatusText);
  // cancel the new window opening
  e.Cancel = true;
}

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/361b6655-3145-4371-b92c-051c223518f2/

...