65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 中可搜索的 TextBox、RichTextBox、ListView 和 TreeView

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.79/5 (58投票s)

2006年7月8日

6分钟阅读

viewsIcon

295597

downloadIcon

4512

一个轻量级的类库,扩展了 Framework 中最流行的编辑器控件,增加了搜索和其他基本功能。

Example application screenshot

引言

当使用一个在控件中显示大量文本的应用程序时,用户会期望通过按 Ctrl-F 来搜索文本短语。不幸的是,对于应用程序开发者来说,虽然添加控件只是从工具箱中拖动它的问题,但添加搜索功能则需要更多的工作。

为了解决这个问题,我开发了一个轻量级的类库,名为 SearchableControls,它包含即用型 SeachableTextBoxSearchableRichTextBoxSearchableListViewSearchableTreeView 控件。这些控件是 Framework 类的直接扩展,因此它们 behaves identically,除了用户可以通过 Ctrl-F 或上下文菜单搜索它们的能力,以及一些其他基本增强功能。对于文本框控件,用户还可以使用标准的 Ctrl-H 快捷方式搜索和替换文本。这些选项也可以通过上下文菜单获得。

查找功能

搜索对话框的设计类似于 Notepad 等标准 Windows 应用程序。功能包括:

  • 在返回第一个结果后,用户可以从搜索对话框继续搜索(“再次搜索”)。
  • 文本输入框是一个组合框,包含先前搜索的历史记录。
  • 可以选择区分大小写的搜索或不区分大小写的搜索。
  • 用户可以选择在搜索中使用通配符(* 或 ?)或完整的正则表达式。
  • 搜索将从文档顶部继续,直到达到原始搜索位置。
  • 如果用户移动或调整搜索对话框控件的大小,当该搜索对话框再次显示在特定可搜索控件上时,其位置将恢复。
  • 对于文本框,当用户选择搜索时,插入符下的单词是默认的搜索词。

附加功能

Example of replace dialog

这些控件的主要功能是搜索。但是,我还添加了一些基本控件中明显缺失的功能。

对于 SearchableRichTextBox,这包括完整的上下文(右键单击)菜单(包括复制、粘贴等)。基本的 RichTextBox 不提供上下文菜单。SearchableTextBox 也提供了相同的功能。(这很有用,因为你无法补充或覆盖 TextBox 的上下文菜单,只能完全替换它。)

还有一个 FindDialog 工具箱控件,允许开发人员将其搜索功能添加到自己的控件中。除了拖放之外,只需要提供一个 SearchRequested 事件处理程序和快捷键代码。

The enhanced context menu

SearchableRichTextBox 还包括通过上下文菜单或键盘格式化文本的能力(Ctrl-B 切换粗体,Ctrl-I 切换斜体,Ctrl-U 切换下划线)。上下文菜单中还有一个用于更改所选文本字体的对话框。

我还添加了一个 Ctrl-A 快捷键来选择控件中的所有文本(除了 TreeView 的扩展,众所周知它不支持多选)。这是 Framework 实现中另一个令人惊讶地缺失的功能。

使用代码

将控件添加到工具箱

从 DLL

可以从二进制库(SearchableControls.dll)直接使用这些控件。在 Visual Studio 2005 中,右键单击窗体设计器工具箱,然后选择“选择项”。然后单击“浏览”按钮,导航并打开 .dll 文件。单击“确定”,这四个控件现在将出现在工具栏的某个位置。

从源代码

下载源代码,并将 SearchableControls.vcproj 添加到您的解决方案中。生成解决方案,控件 *应该* 会自动出现在您的工具箱中。如果这没有发生,关闭并重新打开 Visual Studio 可以促使其发生。

The controls in the toolbox

将控件添加到您的窗体

这就像通常那样,将它们从设计器工具箱拖到您的窗体上。生成并运行您的应用程序,单击新控件,按 Ctrl-F,或右键单击 -> 查找,您将看到查找对话框。输入文本并按 Enter 键或单击搜索按钮将搜索控件的内容。在查找对话框或控件中按 F3 将搜索该字符串的下一个出现。一旦搜索完文档的剩余部分,搜索将从文档的开头开始。

The find dialog

将查找条目添加到父窗体菜单

用户会期望在窗体的“编辑”菜单下找到“查找”。在设计器中,将“编辑”->“查找”菜单项添加到您的窗体,并为其分配一个 Click 事件。添加一个对 SearchableControls.OpenFindDialog(Controls); 的调用,如下所示...

private void findToolStripMenuItem_Click(object sender, EventArgs e)
{
    SearchableControls.Utility.OpenFindDialog(Controls);
}

现在,添加一个“编辑”->“再次查找”菜单项,并为其分配一个 Click 事件。添加一个对 SearchableControls.Utility.FindNext(Controls); 的调用,如下所示...

private void findAgainToolStripMenuItem_Click(object sender, EventArgs e)
{
    SearchableControls.Utility.FindNext(Controls);
}

这些函数允许窗体上有多个可搜索控件,因为它们将根据焦点选择最合适的控件。但是,所有控件都实现了 ISearchable 接口。该接口公开了一个名为 FindDialog() 的单一函数,该函数返回与该控件关联的 FindDialog 对象。调用该对象的 Show() 方法将向用户显示查找对话框。其他功能也可以使用,请参阅源代码或元数据了解更多详细信息。这使得单个控件的查找功能可以由菜单、工具箱或其他任何方式从外部控制。

工作原理

每个控件都提供 KeyDown 事件和上下文菜单项来控制其自己的 FindDialog 对象。该对象会引发 SearchRequestedReplaceRequested 等事件来控制父窗体上的实际搜索行为。父控件使用提供的正则表达式搜索其文本,并使用其正常的选择方法来高亮显示找到的任何文本。

关于 HideSelection 的说明

大多数 Framework 控件都有一个 HideSelection 属性,该属性控制当控件未获得焦点时选择是否可见。由于选择用于指示搜索结果,而搜索结果在查找对话框获得焦点时应该是可见的,因此有必要暂时关闭 HideSelection,否则搜索结果将不可见。

不幸的是,当修改此属性时会看到轻微的闪烁。一种停止闪烁的方法是使用设计器永久地将 HideSelection 设置为 false,以应用于各个控件。如果窗体上只有一个主要控件,这通常是可以接受的。

自定义库

自定义查找对话框

开发人员可以使用 Visual Studio 的设计器轻松自定义查找对话框的外观。可以简单地隐藏不需要的控件。

扩展其他控件以使其可搜索

FindDialog 对象从工具箱拖到您选择的控件上。提供一个 SearchRequested 事件处理程序。

此事件处理程序有一个最低限度的必须执行的功能。它应该在其当前选定内容之后到内容结束的部分进行搜索,然后再从内容顶部到当前选定内容的部分进行搜索。它应该匹配 e.SearchRegularExpression 中提供的正则表达式,例如 e.SearchRegularExpression.IsMatch(myText),选择任何找到的内容,并返回 'true'。如果没有找到匹配项,它应该返回 'false'。

使用正则表达式可以使控件不必处理区分大小写和其他复杂的搜索选项,如通配符。

如上所述,如果您是从 Framework 控件派生,并且使用选择来指示搜索结果,您可能需要关闭 HideSelection。这可以永久关闭,或者在实际进行选择时关闭,如 SearchableControl 控件所做的那样。

进一步发展

可以进一步探索向控件提供预期基本功能的想法。

历史

  • 2006 年 7 月 8 日:初始发布。
  • 2006 年 8 月 8 日:发布 1.2 版本,包括替换功能、搜索历史记录以及作为工具箱控件的 FindDialog
© . All rights reserved.