#1,094 – Disabling Editing Operations in a TextBox

You can disable the cut/copy/paste features in a TextBox by handling the CommandManager.PreviewCanExecute event and checking for the associated editing commands.

TextBox has implicit command bindings to support cut, copy, and paste commands.  When the user executes one of these commands, using the context menu or a keyboard shortcut, the associated routed command is executed, with the TextBox as the source.  You can short-circuit the command by intercepting PreviewCanExecute and making sure that CanExecute returns false.

Markup:
        <TextBox Name="txtSomeText"
                 CommandManager.PreviewCanExecute="txtSomeText_PreviewCanExecute"
                 Width="220" Height="25" Margin="10"/>

Code-behind:

        private void txtSomeText_PreviewCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if ((e.Command == ApplicationCommands.Cut) ||
                (e.Command == ApplicationCommands.Copy) ||
                (e.Command == ApplicationCommands.Paste))
            {
                e.Handled = true;
                e.CanExecute = false;
            }
        }

The editing functions are now disabled. The context menu in the TextBox shows the commands greyed out and corresponding keyboard shortcuts do nothing.

1094-001

#1,071 – How TextBox Reacts to Gaining Keyboard Focus

If you have an application with several TextBox controls, you’ll notice that the TextBox that currently has focus “lights up” by drawing a light blue border around the edge of the TextBox.

1071-001

The TextBox draws the blue border by setting up a trigger in its control template.  You can see the body of the control template by right-clicking the TextBox in Visual Studio from the design surface and selecting Edit Template, followed by Edit a Copy.

1071-002

When you do this, you’ll be asked to give the new copy a name (e.g. TextBoxStyle1).  You’ll then get the full body of the template in the XAML document.

Looking at this template, you’ll see a Trigger on the IsKeyboardFocused property that sets the value of the BorderBrush on a Border element.  It sets it to a static resource, which is defined earlier in the template (to a light blue color).

1071-002 1071-003

#949 – Add a Custom Dictionary for Spell Checking in a TextBox

The built-in spell checker in a TextBox uses a predefined dictionary to look up words.  This means that there may be words flagged as misspelled because they are not in the dictionary.
949-001

You can add a custom dictionary to WPF’s spell checker by creating a lexicon (.lex) file.  To create a custom dictionary, start by creating a .lex file in your project.

949-002

Add any custom words to your dictionary, one line at a time.

949-003

Set the Build Action of the .lex file to Resource.

949-004

In the .xaml file containing the TextBox element, define a namespace that refers to the system assembly.

        xmlns:sys="clr-namespace:System;assembly=system"

And set the SpellCheck.CustomDictionaries element using a Uri to refer to your dictionary.

        <TextBox Name="txtMyText" Margin="5" Height="100"
                 TextWrapping="Wrap"
                 VerticalScrollBarVisibility="Auto"
                 SpellCheck.IsEnabled="True">
            <SpellCheck.CustomDictionaries>
                <sys:Uri>pack://application:,,,/MyDictionary.lex</sys:Uri>
            </SpellCheck.CustomDictionaries>
        </TextBox>

The spell checker now recognizes your custom words.

949-005

#948 – Complete Example of Limiting TextBox Input

If you want to limit text allowed as input to a TextBox, a full strategy for checking text being input should include handling the PreviewKeyDown and PreviewTextInput events, as well as implementing a pasting handler.  Below is a full example that limits text input to alphabetic characters only.

        <TextBox Name="txtMyText" Margin="5" Height="100"
                 TextWrapping="Wrap"
                 AcceptsReturn="True"
                 VerticalScrollBarVisibility="Auto"
                 PreviewTextInput="TextBox_PreviewTextInput"
                 PreviewKeyDown="TextBox_PreviewKeyDown"/>

 

        public MainWindow()
        {
            this.InitializeComponent();
            DataObject.AddPastingHandler(txtMyText, PasteHandler);
        }

        private bool IsAlphabetic(string s)
        {
            Regex r = new Regex(@"^[a-zA-Z]+$");

            return r.IsMatch(s);
        }

        private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            // Prohibit non-alphabetic
            if (!IsAlphabetic(e.Text))
                e.Handled = true;
        }

        private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            // Prohibit space
            if (e.Key == Key.Space)
                e.Handled = true;
        }

        private void PasteHandler(object sender, DataObjectPastingEventArgs e)
        {
            TextBox tb = sender as TextBox;
            bool textOK = false;

            if (e.DataObject.GetDataPresent(typeof(string)))
            {
                // Allow pasting only alphabetic
                string pasteText = e.DataObject.GetData(typeof(string)) as string;
                if (IsAlphabetic(pasteText))
                    textOK = true;
            }

            if (!textOK)
                e.CancelCommand();
        }

#947 – Intercepting Paste Operations in a TextBox

Because the TextBox control automatically supports copy/cut/paste functionality, you may want to intercept paste events to determine if the text to be pasted should be allowed.

You can intercept data being pasted into a TextBox using a pasting handler.  Within the body of the handler, you check the text to be pasted and optionally cancel the paste operation if the text should not be allowed.

You call DataObject.AddPastingHandler when your application starts, specifying the TextBox for which you want to intercept paste events.

        public MainWindow()
        {
            this.InitializeComponent();
            DataObject.AddPastingHandler(txtMyText, PasteHandler);
        }

In the pasting handler, you call the CancelCommand method to reject paste operations.

        private void PasteHandler(object sender, DataObjectPastingEventArgs e)
        {
            TextBox tb = sender as TextBox;
            bool textOK = false;

            if (e.DataObject.GetDataPresent(typeof(string)))
            {
                string pasteText = e.DataObject.GetData(typeof(string)) as string;
                Regex r = new Regex(@"^[a-zA-Z]+$");
                if (r.IsMatch(pasteText))
                    textOK = true;
            }

            if (!textOK)
                e.CancelCommand();
        }

#945 – A Strategy for Limiting Allowed Text in a TextBox

You can limit the text that a user enters into a TextBox by handling the PreviewTextInput event and setting the TextCompositionEventArgs.Handled property to true for characters that you do not want to allow as input.

The PreviewTextInput event will not give you access to every possible keystroke that you might want to use in limiting input.  It’s not fired, for example, when the user presses the spacebar.

You often will also want to handle the PreviewKeyDown event to block keystrokes that don’t trigger PreviewTextInput.

Finally, you may want to intercept Paste events on a TextBox, in order to filter out text that you don’t want a user to paste into the TextBox.

A full strategy for limiting user-entered text might then include:

  • Handling PreviewTextInput and blocking undesirable text
  • Handling PreviewKeyDown and blocking undesirable keystrokes
  • Handling paste operations and blocking undesirable text

#944 – Entering Special Characters into a TextBox

There are sometimes special characters that don’t exist on your keyboard, but that you want to enter into a text-based control (e.g. a TextBox).  To enter these characters:

  • Bring up the Character Map utility (press Windows key and enter “Character Map”)
  • Find that character that you want to insert
  • If the character has a “Keystroke” sequence shown in the lower right corner of the window, you can enter it as follows:
    • Enable Num Lock
    • Hold down Alt key while entering all 4 digits shown, on the numeric keypad

For example, the Character Map utility shows “Alt+0169” as the keystroke combination for a copyright symbol.

944-001

If you hold down the Alt key and type “0169” on the numeric keypad, while a TextBox control has keyboard focus, the copyright symbol will be inserted.

944-002

If keystroke is not shown, you can press Select and then Copy and then paste into your text control.

#943 – Turning on Spell Checking within a TextBox

You can enable automatic spell checking in a TextBox control by setting the SpellCheck.IsEnabled property to true.

        <TextBox Margin="5" Height="100"
                 TextWrapping="Wrap"
                 AcceptsReturn="True"
                 VerticalScrollBarVisibility="Auto"
                 SpellCheck.IsEnabled="True"/>

When spell-checking is enabled, words that are misspelled are underlined with a red squiggly line.

943-001

 

When the spell-checker flags a spelling error, you can right-click on the red line to see a menu of suggested corrections.

943-002

 

Selecting one of the suggestions will cause the misspelled text to be replaced with the correction.

943-003

#942 – Text Justification in a TextBox

In typography, justification is the alignment of the edges of a block of text.  Text can be “flush left”, indicating that the left edges of the lines are aligned with each other and the right edges are ragged–i.e. not aligned.  Text can also be “flush right” (right ends of lines are aligned), “justified” (both edges line up), or centered (both edges ragged).

Like the TextBlock, the TextBox control allows setting justification using the TextAlignment property.  When set, text is continually adjusted to fulfill the desired alignment, as the user types.

  • Left – Left justify the text  (default)
  • Right – Right justify the text
  • Center – Center the text
  • Justify – Insert spaces between words to line up both edges of text  (only takes effect if line fills up available width and then wraps)
        <TextBox Margin="5" Height="100"
                 TextAlignment="Center"
                 TextWrapping="Wrap"
                 AcceptsReturn="True"
                 VerticalScrollBarVisibility="Auto"/>

942-001

#941 – Forcing Uppercase or Lowercase in a TextBox

If you want to limit a user to entering only uppercase or only lowercase in a particular TextBox, you can set the CharacterCasing property as follows:

  • Normal – Default setting, allows both uppercase and lowercase
  • Lower – Force all entered text to lowercase
  • Upper – Force all entered text to uppercase

This setting impacts text typed or pasted into the TextBox.  It does not convert text set through code or via data binding.

With CharacterCasing=”Lower”:

941-001

With CharacterCasing=”Upper”:

941-002