单击并突出显示C#Web浏览器

时间:2009-07-07 06:57:14

标签: c# dom

在我开始编码之前,我想我会看到这里是否有人知道已经建立的任何开源(或付费)等价物。

我正在寻找一个浏览器控件,用户可以在其中预览网页,然后突出显示它的元素,一旦突出显示,我就可以获得所选元素的div或id。

有没有人见过这样的事情?

2 个答案:

答案 0 :(得分:9)

这是使用.NET WebBrowser控件的原始版本,它使用Internet Explorer。

namespace WindowsFormsApplication1
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Windows.Forms;

    public partial class Form1 : System.Windows.Forms.Form
    {
        private HtmlDocument document;

        private IDictionary<HtmlElement, string> elementStyles = new Dictionary<HtmlElement, string>();

        public Form1()
        {
            InitializeComponent();
        }

        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            this.Text = e.Url.ToString();
            this.document = this.webBrowser1.Document;
            this.document.MouseOver += new HtmlElementEventHandler(document_MouseOver);
            this.document.MouseLeave += new HtmlElementEventHandler(document_MouseLeave);
        }

        private void document_MouseLeave(object sender, HtmlElementEventArgs e)
        {
            HtmlElement element = e.FromElement;
            if (this.elementStyles.ContainsKey(element))
            {
                string style = this.elementStyles[element];
                this.elementStyles.Remove(element);
                element.Style = style;
            }
        }

        private void document_MouseOver(object sender, HtmlElementEventArgs e)
        {
            HtmlElement element = e.ToElement;
            if (!this.elementStyles.ContainsKey(element))
            {
                string style = element.Style;
                this.elementStyles.Add(element, style);
                element.Style = style + "; background-color: #ffc;";
                this.Text = element.Id ?? "(no id)";
            }
        }
    }
}

答案 1 :(得分:3)

我有类似的需求,最初发布的代码是一个巨大的帮助。我想回复原作者的善意。

提供的答案不充分。它只回答请求的第一部分:突出显示呈现的HTML。它不能解决请求的后半部分,其中C#程序可以判断选择了哪个节点。

当鼠标进入表格并向所需的渲染区域移动时,高亮显示将跟随鼠标。这意味着鼠标可能会访问许多HTML元素。

那么C#如何告诉用户想要哪个元素呢?

程序必须允许用户单击所需的渲染区域。点击应该被C#程序捕获。此外,C#应禁用传递给元素的点击(例如,如果它的Anchor元素不希望点击跟随链接)。

我在我的程序中解决了这个问题,如下所示:

(1)在'document complete'事件中,我为文档级别的click事件添加了一个陷阱(文档只有一次):

        HtmlDocument htmlDoc = webBrowser.Document;

        _document = webBrowser.Document;

        //-- add our handler only once
        if (!_documentHandlers.Contains(_document))
        {
            _document.MouseOver += new HtmlElementEventHandler(document_MouseOver);
            _document.MouseLeave += new HtmlElementEventHandler(document_MouseLeave);

            mshtml.HTMLDocumentEvents2_Event iEvent;
            IHTMLDocument2 currentDoc = (IHTMLDocument2) webBrowser.Document.DomDocument;

            iEvent = (mshtml.HTMLDocumentEvents2_Event) currentDoc;
            iEvent.onclick += new mshtml.HTMLDocumentEvents2_onclickEventHandler(clickDocumentHandler);

            _documentHandlers.Add(_document);
        }

对于同一文档,可以多次触发“已完成文档”事件(尝试CNN.com)。 '_documentHandlers'变量是一个HashSet,以确保我们只为给定的文档添加一次处理程序。

(2)我还选择在元素级别捕获点击。在'鼠标悬停'上我添加了:

                mshtml.HTMLElementEvents2_Event iEvent;
                iEvent = element.DomElement as mshtml.HTMLElementEvents2_Event;
                if (iEvent == null)
                    return;
                iEvent.onclick += new mshtml.HTMLElementEvents2_onclickEventHandler(clickElementHandler);

并且在'鼠标离开'时我取消注册了点击处理程序:

                mshtml.HTMLElementEvents2_Event iEvent;
                iEvent = element.DomElement as mshtml.HTMLElementEvents2_Event;
                if (iEvent == null)
                    return;
                iEvent.onclick -= new mshtml.HTMLElementEvents2_onclickEventHandler(clickElementHandler);

(3)点击处理程序很简单:

    private bool clickDocumentHandler(IHTMLEventObj pEvtObj)
    {
        IHTMLElement element = (mshtml.IHTMLElement)pEvtObj.srcElement;

        pEvtObj.cancelBubble = true;
        pEvtObj.returnValue = false;

        return false;
    }

    private bool clickElementHandler(IHTMLEventObj pEvtObj)
    {
        IHTMLElement element = (mshtml.IHTMLElement)pEvtObj.srcElement;

        pEvtObj.cancelBubble = true;
        pEvtObj.returnValue = false;

        return false;
    }

请注意,它们会取消事件的冒泡并返回值“false”,以防止点击向上渗透。

在这些处理程序中,您可以添加特定代码以保存被单击的元素,然后在应用程序的其他位置使用它。

请注意,在元素级别,并非每个IHTMLElement都支持onclick处理程序,因此检查null。

-Enjoy 大卫