Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A User-Searchable TextBox, RichTextBox, ListView, and TreeView in C#

0.00/5 (No votes)
18 Aug 2006 4  
A lightweight class library that extends the Framework's most popular editor controls to include search and other basic functionality.

Example application screenshot

Introduction

When using an application that presents a lot of text in controls, users will expect to be able to search for text phrases by pressing Ctrl-F. Unfortunately for the application developer, while adding the control is just a matter of dragging it from the toolbox, adding the search functionality is a bit more work.

To solve this, I developed a lightweight class library, SearchableControls, that contains ready-to-use SeachableTextBox, SearchableRichTextBox, SearchableListView, and SearchableTreeView controls. These are straight extensions of the Framework classes, and so they behave identically, other than the user's ability to search them with Ctrl-F or the context menu, and some other basic enhancements. In the case of the text box controls, users can also search and replace text using the standard Ctrl-H shortcut. These options are also available from the context menu.

Find features

The search dialog is designed to behave like standard Windows applications such as Notepad. Features include;

  • After the first result is returned, the user can continue to search ("search again") from the search dialog.
  • The text entry box is a combo box featuring a history of previous searches.
  • Either a case-sensitive or case-insensitive search can be selected.
  • The user can select to use wildcards (* or ?) or full regular expressions in the search.
  • Searches will continue from the top of the document until the original search position is reached.
  • If the user moves or resizes the search dialog control, its position will be restored if the search dialog is displayed again on that particular searchable control.
  • For text boxes, the word under the caret when the user selects search is the default search term.

Additional features

Example of replace dialog

The main feature of these controls is the search function. However, I have also added some functionality conspicuously absent from the basic controls.

For SearchableRichTextBox, this includes a full context (right click) menu (including Copy, Paste, etc.). The basic RichTextBox does not supply a context menu. The same is supplied for the SearchableTextBox. (This is useful because you cannot supplement or override TextBox's context menu - only replace it completely.)

Also available is a FindDialog toolbox control which allows developers to add search functionality to their own controls. Other than a drag and drop, it is only necessary to supply a SearchRequested event handler and the shortcut code.

The enhanced context menu

SearchableRichTextBox also includes the ability to format text from the context menu or keyboard (Ctrl-B toggles bold, Ctrl-I toggles italics, and Ctrl-U toggles underlining). A dialog to change the font of the selected text is also on the context menu.

I have also added a shortcut key for Ctrl-A to select all the text in the controls (other than the extension of TreeView, which famously does not support multiple selection). This is another feature surprisingly absent from the Framework implementations.

Using the code

Getting the controls into the toolbox

From the DLL:

The controls can be used directly from the binary library (SearchableControls.dll). In Visual Studio 2005, right click on the form designer toolbox, and select Choose Items. Then click the Browse button, and navigate to and open the .dll. Click OK, and the four controls will now be added somewhere to the toolbar.

From the source:

Download the source, and add the SearchableControls.vcproj to your solution. Build the solution, and the controls should appear in your toolbox automatically. If this doesn't happen, closing and re-opening Visual Studio can encourage it.

The controls in the toolbox

Getting the controls into your form

This is a matter of dragging them to your form from the designer toolbox in the usual way. Build and run your application, click on the new control, press Ctrl-F, or right click->Find, and you will see the Find dialog. Typing the text and pressing Return or clicking the Search button will search the contents of the control. Pressing F3 in the Find dialog or in the control will search for the next occurrence of the string. Once the remainder of the document has been searched, searches will take place from the start of the document.

The find dialog

Adding the Find entries to the parent form menu

Users will expect to see Find under the form's Edit menu. In the designer, add the Edit->Find menu item to your form and give it a Click event. Add a call to SearchableControls.OpenFindDialog(Controls); as below...

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

Now, add an Edit->Find Again menu item, and give it a Click event. Add a call to SearchableControls.Utility.FindNext(Controls); as below ..

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

These functions allow multiple searchable controls on a form as they will select the most appropriate based on focus. However, all controls apply the interface ISearchable. This exposes a single function FindDialog() which returns the FindDialog object associated with that control. Calling Show() on this object will present the Find dialog to the user. Other functionality is available, see the source code or metadata for more details. This allows an individual control's Find functionality to be controlled externally by menus, toolboxes, or whatever.

How it works

Each control supplies KeyDown events and context menu items to control its own FindDialog object. This object raises events such as SearchRequested and ReplaceRequested to control the actual search behaviour on the parent form. The parent control searches its text with a supplied regular expression, and uses its normal selection method to highlight any found text.

A note about HideSelection

Most Framework controls have a HideSelection property which controls if selections are visible when the control is not focused. As selection is used to indicate search results which should be visible when the Find dialog is focused, it is necessary to turn off HideSelection temporarily, or search results will be invisible.

Unfortunately, a slight flicker is visible when this property is altered. One way to stop that is to set HideSelection to false permanently on individual controls, using the designer. This is usually acceptable if there is only one major control on the form.

Customizing the library

Customizing the Find dialog

It is a simple matter for developers to customize the appearance of the Find dialog using Visual Studio's designer. Unwanted controls can simply be hidden from the view.

Extending other controls to be searchable

Drag a FindDialog object from the toolbox to your chosen control. Supply a SearchRequested event handler.

This event handler has a minimum function it is required to perform. It is expected to search its content from after the current selection until the end, and then from the top of the content until the current selection. It is expected to match text against the regular expression supplied in e.SearchRegularExpression, e.g., e.SearchRegularExpression.IsMatch(myText), select any found content, and return 'true'. If no matches are found, it is expected to return 'false'.

Using regular expressions frees the controls from having to process case sensitivity and other exotic search options such as wildcards.

As mentioned above, if you are deriving from a Framework control, and using selection to indicate search results, you will probably need to turn off HideSelection. This can either be done permanently, or when selections are actually made, as with the SearchableControl controls.

Further development

The idea of supplying the expected basic functionality to controls could be explored further.

History

  • 08 July 2006 :- Initial release.
  • 08 Aug 2006 :- Version 1.2 release, including replace functionality, search history, and FindDialog as a toolbox control.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here