1

我需要实现按 Ctrl+F 时弹出的查找对话框提供的搜索功能。

我有一个文本框,用户可以在其中输入要搜索的字符串,还有一个“搜索”按钮。单击按钮时,需要突出显示 HTML 文档中的匹配项 - 与“查找”对话框中的实现完全相同。

有没有办法绕过 WebBrowser 控件中的“查找”对话框?是否可以将搜索参数发送到“查找”功能?

在此先感谢您的帮助。

编辑

理想情况下,我将能够使用“查找”对话框提供的全部功能,包括“仅匹配整个世界”、“匹配大小写”和“突出显示所有匹配项”...

4

2 回答 2

0

我在这方面遇到了很多困难,但我终于找到了一个可行的解决方案。它有点混乱,但它可以按预期用于 Winforms WebBrowser 控件。这是在 .Net 4.0 中导入了 Microsoft.mshtml 7.0.3300 参考。

using mshtml;

private int _findClicks = 0;
private string _searchText = "";

public string SearchText
    {
        get { return _searchText; }
        set
        {
            if (value.ToUpper() != _searchText)
            {
                ClearFind();
                _searchText = value.ToUpper();
                txtSearch.Text = value.ToUpper();

                _findClicks = 0;
            }
        }
    }

private void btnSearch_Click(object sender, EventArgs e)
    {
        SearchText = txtSearch.Text;
        if (_findClicks == 0)
            FindFirst();
        else
            FindNext();
    }

 /// <summary>
    /// Search through all text to find. Sets all occurrences to background color yellow.
    /// </summary>
    private void FindFirst()
    {
            if (_searchText == "")
                return;
            IHTMLDocument2 doc = webBrowser1.Document.DomDocument as IHTMLDocument2;
            IHTMLSelectionObject sel = doc.selection;
            IHTMLTxtRange range = sel.createRange() as IHTMLTxtRange;
            //Mark all occurrences with background color yellow
            while (true)
            {
                if ((range.findText(_searchText)) && (range.htmlText != "span style='background-color: yellow;'>" + _searchText + "</span>"))
                {
                    range.pasteHTML("<span style='background-color: yellow;'>" + _searchText + "</span>");
                }
                else
                    break;
            }
            //Move to beginning and select first occurence.
            range.moveStart("word", -9999999);
            range.findText(_searchText);
            range.select();
            _findClicks++;
        }

/// <summary>
    /// Finds next occurrence of searched text and selects it.
    /// </summary>
    private void FindNext()
    {
            if (_searchText == "")
                return;
            IHTMLDocument2 doc = webBrowser1.Document.DomDocument as IHTMLDocument2;
            IHTMLSelectionObject sel = doc.selection;
            IHTMLTxtRange range = sel.createRange() as IHTMLTxtRange;
            range.collapse(false); // collapse the current selection so we start from the end of the previous range

            if (range.findText(_searchText, 1000000, 0))
            {
                range.select();
            }
            else // If at end of list, go to beginning and search one more time.
            {
                range.moveStart("word", -9999999);
                if (range.findText(_searchText, 1000000, 0))
                {
                    range.select();
                }
            }
    }

/// <summary>
    /// Remove highlighting on all words from previous search.
    /// </summary>
    private void ClearFind()
    {
            if (_searchText == "" || webBrowser1.ReadyState != WebBrowserReadyState.Complete)
                return;
            IHTMLDocument2 doc = webBrowser1.Document.DomDocument as IHTMLDocument2;
            IHTMLSelectionObject sel = doc.selection;
            IHTMLTxtRange range = sel.createRange() as IHTMLTxtRange;
            range.moveStart("word", -9999999);
            while (true)
            {
                if ((range.findText(_searchText)) && (!range.htmlText.Contains("span style='background-color: white")))
                {
                    range.pasteHTML("<span style='background-color: white;'>" + _searchText + "</span>");
                }
                else
                    break;
            }

    }

同样,这有点混乱,可能会被清理很多。这几乎复制了 Web 浏览器控件中 Ctrl+F 功能的基础知识。希望它对所有未来的读者有所帮助。

于 2014-11-04T15:36:03.310 回答
0

自己做并不难,您只需将搜索文本框中的内容替换为以下内容,假设搜索词是“hello”,然后将所有出现的 hello 替换为以下内容:

<font color="yellow">hello</font>

当然,此 HTML 可以替换为 SPAN 标签(这是 DIV 标签的内联版本,因此您的行不会使用 SPAN 中断,但会使用 DIV)。但无论哪种情况,这两个标签都有一个 style 属性,您可以使用 CSS 更改其颜色或与 CSS 兼容的无数其他属性,如下所示:

<SPAN style="background-color: yellow;">hello</SPAN>

当然,还有无数其他方法可以使用 HTML 更改颜色,如果需要,请随时在网络上搜索更多信息。

现在,您可以使用 dotnet 中的 .Replace() 函数来执行此操作(替换搜索到的文本),非常简单。因此,您可以使用 .DocumentText 将整个文档作为字符串获取,并且一旦所有出现的内容都被替换(使用 .Replace()),您可以将其设置回 .DocumentText(因此,您使用 .DocumentText 来获取原始文件字符串,并使用替换的字符串设置 .DocumentText)。当然,您可能不想对实际 HTML 中的项目执行此操作,因此您可以通过对所有元素执行 For Each 循环来遍历页面上的所有元素,如下所示:

For Each someElement as HTMLElement in WebBrowser1.Document.All

每个元素都有一个 .InnerText/.InnerHTML 和 .OuterText/.OuterHTML ,您可以获取(读取)和设置(用替换文本覆盖)。

当然,根据您的需要,您可能只想替换和覆盖 .InnerText 和/或 .OuterText。

如果您需要更多帮助,请告诉我。无论哪种情况,我都想知道它是如何为您解决的,或者我们是否可以做任何其他事情来为您的问题增加价值。干杯。

于 2012-09-13T14:41:42.687 回答