#940 – Easy Selection of Entire Words in a TextBox

By default, as the user drags the mouse in a TextBox while holding the left mouse button down, text is selected one character at a time.

For example, in the TextBox shown below, if I click in the middle of the word “years” and drag the cursor into the middle of the word “later”, a portion of each word is selected.

940-001

 

If you want a user to easily select entire words within the text, you can set the AutoWordSelection property of the TextBox to true.  Now, as I drag the cursor into the second word, both words are automatically selected.

940-002

 

Even with auto word selection enabled, the user can select a portion of the word by selecting the full word and then moving the cursor backwards.

#939 – Retrieving Individual Lines of Text from a TextBox

The LineCount property of a TextBox can be used to retrieve the current number of lines of text in a TextBox.  If the text wraps to multiple lines, this property will reflect the visible number of wrapped lines that the user sees.

The TextBox.GetLineText method allows reading an individual line of text based on a 0-based index.

Assume that we have a TextBox that wraps some text:

        <TextBox Name="txtTest" Margin="5" Height="100"
            Text="{Binding SomeText}"
            TextWrapping="Wrap"
            SelectionBrush="Purple"
            VerticalScrollBarVisibility="Auto"/>
        <Button Content="Inspect" Click="Button_Click"
            HorizontalAlignment="Center" Padding="10,5"/>

We can then read each visible line when the button is clicked.

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            StringBuilder sbInfo = new StringBuilder(string.Format("# lines = {0}", txtTest.LineCount));
            sbInfo.AppendLine();

            for (int i = 0; i < txtTest.LineCount; i++)
                sbInfo.AppendLine(txtTest.GetLineText(i));

            MessageBox.Show(sbInfo.ToString());
        }

939-001
If we change the size of the TextBox, causing the lines to wrap differently, the LineCount will change.

939-002

#938 – Changing the Selected Text Color in a TextBox

You can change the color of the brush that is used to show selected text in a TextBox by setting the SelectionBrush property.  You’ll typically set this property in XAML to the name of the color that you want the text selection rendered in.  This property defaults to a SolidColorBrush whose color is hex 3399FF (R=51, G=153, B=255), or light blue.

        <TextBox Name="txtTest" Margin="5" Height="100"
            Text="{Binding SomeText}"
            TextWrapping="Wrap"
            SelectionBrush="Purple"
            VerticalScrollBarVisibility="Auto"/>

938-001
The opacity used by the selection brush defaults to 0.4, but you can set it to be more (>0.4) or less (<0.4) opaque by changing the SelectionOpacity property.

        <TextBox Name="txtTest" Margin="5" Height="100"
            Text="{Binding SomeText}"
            TextWrapping="Wrap"
            SelectionBrush="Purple"
            SelectionOpacity="0.2"
            VerticalScrollBarVisibility="Auto"/>

938-002

#937 – Selecting Text in a TextBox from Code

You can select text in a TextBox from code by using the Select method.  This method accepts the following two parameters:

  • start – 0-based index for start of selection (int)
  • length – number of characters to select (int)

Note that if the TextBox doesn’t currently have focus, the selected text will not be highlighted.

Assume that we have a TextBox, some labels displaying selected text and a Button:

        <TextBox Name="txtTest" Margin="5" Height="100"
            Text="{Binding SomeText}"
            TextWrapping="Wrap"
            VerticalScrollBarVisibility="Auto"
            SelectionChanged="TextBox_SelectionChanged"/>
        <Label Content="{Binding SelectedText}"/>
        <StackPanel Orientation="Horizontal">
            <Label Content="{Binding SelectionStart}"/>
            <Label Content="{Binding SelectionLength}"/>
        </StackPanel>
        <Button Content="Select Something" Click="Button_Click"/>

The code below then selects some text when the button is pressed.

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            // Select 10 characters, starting 6th character
            txtTest.Select(5, 10);

            // Give focus back to TextBox, so that it
            // highlights selected text
            txtTest.Focus();
        }

937-001

#936 – TextBox Properties that Reflect Currently Selected Text

The following properties of a TextBox are updated whenever the user changes the currently selected text in a TextBox.

  • SelectedText – the currently selected text (string)
  • SelectionStart – 0-based index into the Text property for the start of the selection  (int)
  • SelectionLength – number of characters selected (int)

The SelectionChanged event will fire whenever the currently selected text changes.

Below, we wire up the SelectionChanged event, capture the values of these properties, and then bind to those values.

        <TextBox Margin="5" Height="100"
            Text="{Binding SomeText}"
            TextWrapping="Wrap"
            VerticalScrollBarVisibility="Auto"
            SelectionChanged="TextBox_SelectionChanged"/>
        <Label Content="{Binding SelectedText}"/>
        <StackPanel Orientation="Horizontal">
            <Label Content="{Binding SelectionStart}"/>
            <Label Content="{Binding SelectionLength}"/>
        </StackPanel>
        private void RaisePropertyChanged(string propName)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }

        public string SelectedText { get; set; }
        public int SelectionStart { get; set; }
        public int SelectionLength { get; set; }

        private void TextBox_SelectionChanged(object sender, RoutedEventArgs e)
        {
            SelectedText = ((TextBox)sender).SelectedText;
            SelectionStart = ((TextBox)sender).SelectionStart;
            SelectionLength = ((TextBox)sender).SelectionLength;

            RaisePropertyChanged("SelectedText");
            RaisePropertyChanged("SelectionStart");
            RaisePropertyChanged("SelectionLength");
        }

936-001

#935 – Setting an Undo Limit for a TextBox

By default, a TextBox control has an undo limit of 100.  That is, it keeps track of the most recent 100 edits that you’ve made, allowing you to undo them one at a time.

You can change the number of operations that the TextBox remembers by setting its UndoLimit property.  For example, if you set this value to 3, the TextBox will only allow you to undo the most recent three edits.

You may want to increase the value of UndoLimit so that the user of your application has the ability to undo a larger number of recent operations.

    <TextBox Margin="5" UndoLimit="1000"
        Text="{Binding SomeText}"
        TextWrapping="Wrap"
        VerticalScrollBarVisibility="Auto"/>

On the other hand, you may want to reduce the value of UndoLimit so that your application does need to allocate memory for all of the recent changes to a TextBox.

#934 – TextBox Has Built-In Undo Functionality

The TextBox control in WPF has built-in Undo and Redo functionality, allowing you to undo changes to the content of the TextBox or to re-apply (redo) changes that you’ve undone.

Assume that you have a TextBox with some text:

934-001

Now assume that you double-click to select the first word and then press Delete to delete it.

934-002

Do this two more times, so that you’ve delete the first three words of the text, one at a time.

934-003

You’ve now made three distinct changes to the text in the TextBox, one at a time.  You can delete the most recent change by pressing Ctrl+Z, which executes an undo operation.  This will restore the word that was most recently deleted.

934-004

You can press Ctrl+Z two more times, restoring the other words that you deleted.

934-005

You can redo a change (e.g. delete a word) by pressing Ctrl+Y.

934-006