Click here to Skip to main content
15,879,474 members
Articles / Desktop Programming / WPF

WPF TextBox with PreviewTextChanged event for filtering

Rate me:
Please Sign up or sign in to vote.
4.60/5 (3 votes)
2 Aug 2011CPOL3 min read 47.5K   2.1K   9   3
A WPF control, PreviewTextBox, used to filter/validate user input.

Introduction

This article describes the PreviewTextBox control (derived from the standard WPF TextBox control). This control adds a PreviewTextChanged event to allow for simple and flexible validation of user input.

By subscribing to this event, or overriding the OnPreviewTextChanged method, almost any imaginable filtering can be easily implemented. For example, the control could form the basis for a WPF equivalent to the WinForm MaskedTextBox control. However, this exceeded my requirements.

The demo project also provides a sample control, IntTextBox, derived from it. The sample control limits the user to entering valid integral values. The demo project simply displays this sample control to show it in action.

Background

Previously, I wrote an article about a WinForm control that served a similar purpose. I found a need for this control in WPF, but wanted one native to the WPF environment. This article describes the new implementation. Hopefully, others may find it useful.

Many similar articles exist. However, none covered all of the different ways a user might introduce bad data. Most focused solely on user-typed input and paste.

Using the Code

To the end user, PreviewTextBox is nearly identical to the standard WPF TextBox control. It simply adds the PreviewTextChanged event I wish MS had included in their implementation.

To use it in XAML, simply add a namespace to the root element, like so:

XML
xmlns:ex="clr-namespace:Extended.Windows.Controls"

A full-context example of this can be found in the MainWindow.xaml file from the demo project, and looks like this:

XML
<Window x:Class="PreviewText.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ex="clr-namespace:Extended.Windows.Controls"
    Title="Preview Text" Height="100" Width="225">

Once you've done this, you can reference any control in the Extended.Windows.Controls CLR namespace by preceding them with the ex prefix in the XAML. For example:

XML
<ex:IntTextBox Grid.Row="0" Grid.Column="1" Margin="4,0" />

Two approaches to validation are possible. In the first, the end user simply subscribes to the PreviewTextChangedEvent. Setting e.Handled to true in the event handler will cancel the change.

In the second, used in the IntTextBox sample control, the OnPreviewTextChanged method is overridden. By creating a derived control, the same validation can more easily be re-used in XAML.

For those interested in how PreviewTextBox is implemented, the code is fully commented. I will briefly describe the highlights of that implementation in the remainder of this article.

There are three major integration points where native WPF TextBox events are intercepted to raise the PreviewTextChanged event. These include PreviewTextInput, PreviewKeyDown, and PreviewExecutedEvent (from the command manager).

In all cases, the code predicts the resulting text (as if the change had already occurred). This resulting text is provided as a property of the arguments to the PreviewTextChanged event. If the handler sets e.Handled to true in the PreviewTextChanged handler, this same value is communicated to the original event handler.

PreviewTextInput is raised for most of what a user types. It is intercepted by overriding the OnPreviewTextInput method.

PreviewKeyDown is raised when a user presses a key. It is intercepted separately from PreviewTextInput because, for some reason, the space character does not raise that event. It is intercepted by overriding the OnPreviewKeyDown method.

PreviewExecutedCommand is raised for many different editing commands (delete, backspace, etc.) and application commands (Cut, Paste, etc.). It is intercepted by adding a handler in the overridden OnInitialized method. The handler is added as follows:

C#
AddHandler(CommandManager.PreviewExecutedEvent,
  new ExecutedRoutedEventHandler(previewExecutedEvent), true);

This results in the previewExecutedEvent method being invoked each time the user initiates one of these commands for the PreviewTextBox control.

Points of Interest

The code does not currently intercept programmatic assignments to the Text property. I was unable to reliably intercept such changes. Also, they were not necessary for filtering user input.

The code does not, by default, intercept the application commands Undo and Redo. The mechanism for intercepting these commands is rather messy. Because the undo stack is not available, it requires an undo and redo (or the reverse) simply to predict the text that would result. A property PreviewUndoEnabled is provided to enable this optional logic. However, with proper validation elsewhere, neither Undo or Redo can introduce invalid values.

History

  • 8/1/2011 - The original version was uploaded.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
Eric is a Senior Software Engineer with 30+ years of experience working with enterprise systems, both in the US and internationally. Over the years, he’s worked for a number of Fortune 500 companies (current and past), including Thomson Reuters, Verizon, MCI WorldCom, Unidata Incorporated, Digital Equipment Corporation, and IBM. While working for Northeastern University, he received co-author credit for six papers published in the Journal of Chemical Physics. Currently, he’s enjoying a little time off to work on some of his own software projects, explore new technologies, travel, and write the occasional article for CodeProject or ContentLab.

Comments and Discussions

 
GeneralMy vote of 4 Pin
ISanti9-Dec-15 23:30
ISanti9-Dec-15 23:30 
QuestionUseeful Pin
ISanti9-Dec-15 23:23
ISanti9-Dec-15 23:23 
I was looking for this exactly, and also convinced me that I should not worry about Undo/Redo for format validation.

Thanks
Sorry for my bad English

AnswerRe: Useeful Pin
Eric Lynch19-Dec-15 5:18
Eric Lynch19-Dec-15 5:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.