我一定是个异端,因为我想要一个同时具有NewWindow2和GetElementsByTagName的C#浏览器



显然,你不能既有蛋糕又吃。

我目前正在我的应用程序中使用System.Windows.Forms.WebBrowser。程序当前依赖于使用GetElementsByTagName函数。我用它来收集特定类型的所有元素("input"或"textarea"),这样我就可以对它们进行排序并返回特定元素的值。这是该函数的代码(我的WebBrowser名为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事件。如果能帮我把新窗户送到我需要的地方,我会非常高兴。在该WebBrowser中执行此操作的代码是(frmNewWindow是一个简单的表单,只包含另一个名为web2的WebBrowser(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活动来复制这种功能。

我也不知道如何使用AxSHDocVw.WebBrowser复制我上面详细介绍的FetchValue功能。它似乎以一种完全不同的方式做事,我所有关于如何做事的知识都是无用的。

我知道我是一个病态、扭曲的人,因为我幻想在一个应用程序中使用这两种东西。但你能在心里找到帮助这个愚蠢的理想主义者的方法吗?

我再也不能依赖解决方法了,不得不放弃System.Windows.Forms.WebBrowser。我需要NewWindow2。

我最终想出了如何使用AxWebBrowser来完成我需要的东西。我最初的帖子要求为System.Windows.Forms.WebBrowser上的NewWindow2提供解决方案,或者为.GetElementsByTagName提供AxWebBrowser替代方案。该替代方案需要大约4倍的代码,但可以完成任务。我认为发布我的解决方案是明智的,因为后来谷歌员工也有同样的困惑。(还有一种更好的方法)

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");
   }
}

网络浏览器。Document被转换为IHTMLDocument2,然后IHTMLDocument2中的框架被放入IHTMLFramesCollection2,然后我将特定的所需框架转换为IHTMLWindow2(您可以通过索引#或名称选择框架),然后我把框架的.Document成员转换为IHTMLDocument2(为了方便起见,最初使用的框架)。从那里,IHTMLDocument2的.all.tags()方法在功能上与旧的WebBrowser.Document.GetElementsByTagName()方法相同,只是它需要IHTMLElementCollection而不是HTMLElementCollection。然后,您可以foreach集合,单个元素需要是IHTMLElement,并使用.getAttribute来检索属性。请注意,g是小写的。

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/

我看到的唯一解决方案是几年前的一个好方案,名为csExWb2,现在在谷歌代码上。

它为您提供了一个ExWebBrowser控件,但可以完全访问IE提供的所有接口和事件。我用它在winforms托管的html编辑器中对元素进行深入而肮脏的控制。

记住,直接跳进去可能有点跳跃。

相关内容

  • 没有找到相关文章

最新更新