TX Text Control .NET for WPF

Keyboard Shortcuts

Topic

Which keys does the WPF TextControl understand before your application adds any? The tables below answer the question for moving the caret, editing, hyphens and tables, so that you can document them for your users and avoid them when you add shortcuts of your own. The last sections add such shortcuts in a KeyDown handler and give Enter a new meaning in a PreviewKeyDown handler.

Mouse actions, such as a triple-click to select a paragraph, are listed on Selections and Caret Position.

Move the Caret

KeysAction
Left Arrow, Right ArrowMoves the caret one character to the left or right
Up Arrow, Down ArrowMoves the caret one line up or down
Ctrl+Left ArrowMoves the caret to the beginning of the current word
Ctrl+Right ArrowMoves the caret to the beginning of the next word
HomeMoves the caret to the beginning of the line
EndMoves the caret to the end of the line
Ctrl+HomeMoves the caret to the start of the text
Ctrl+EndMoves the caret to the end of the text
Page Up, Page DownScrolls up or down by the height of the visible area minus one line, if there is a vertical scroll bar
Shift+Page Up, Shift+Page DownScrolls the document horizontally
Ctrl+Page Up, Ctrl+Page DownZooms the document in or out

With Shift held down, every key that moves the caret extends the selection to the new position. Shift+End, for example, selects the rest of the line.

Edit Text

KeysAction
Shift+EnterInserts a line break without starting a new paragraph
Ctrl+EnterInserts a page break
Ctrl+Shift+EnterInserts a column break, so that the text continues in the next column of a multi-column section
Ctrl+Shift+SpacebarInserts a non-breaking space
DeleteDeletes the selected text
Ctrl+Backspace, Shift+BackspaceDeletes the previous word
Ctrl+CCopies the selected text to the clipboard
Ctrl+XCopies the selected text to the clipboard and deletes it
Ctrl+VPastes the content of the clipboard in place of the selection
Ctrl+ZUndoes the last action
Ctrl+YRestores the last undone action

The methods behind the clipboard and undo keys are described on Clipboard Operations and Undo and Redo.

Insert Hyphens and Dashes

KeysInsertsWord may be divided there
Hyphen (-)A hyphen or minus signYes
Ctrl+HyphenAn end-of-line hyphen, which is not visible unless the word is divided at that pointYes
Ctrl+Shift+HyphenA hyphen for compound words that keeps the parts on one lineNo
Ctrl+Minus on the numeric keypadAn en dashYes
Ctrl+Alt+Minus on the numeric keypadAn em dashYes

For automatic hyphenation, see Spell Checking and Hyphenation.

Keys in Tables

KeysAction
TabSelects the next table cell. In the last cell of a table, it adds a new row at the end of the table.
Shift+TabSelects the previous table cell
Ctrl+TabInserts a tab character in the cell
EnterAt the first input position of a document that begins with a table, inserts an empty line in front of the table

Outside of tables, the dependency property AcceptsTab decides what Tab does: with true, it types a tab character; with false, it moves the keyboard focus to the next control of the window. Set it in XAML with AcceptsTab="True".

Form fields have keys of their own, such as the Spacebar to check a check box or open a drop-down list. They are listed on Form Fields and Conditional Instructions.

Add Your Own Shortcuts

Key presses raise the KeyDown routed event of the control. A handler checks the key and the modifier keys, calls a method of the editor and sets e.Handled so that the editor ignores the key. Connect the handler in MainWindow.xaml:

<Window x:Class="SampleApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:WPF="clr-namespace:TXTextControl.WPF;assembly=TXTextControl.WPF"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <WPF:TextControl x:Name="textControl1" KeyDown="TextControl1_KeyDown" />
    </Grid>
</Window>

The handler in MainWindow.xaml.cs opens the Find and Replace dialog boxes with Ctrl+F and Ctrl+H, selects all text with Ctrl+A and switches between insert and overwrite mode with the Insert key. Replace SampleApp with the namespace of your project:

using System.Windows;
using System.Windows.Input;
using TXTextControl;

namespace SampleApp;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void TextControl1_KeyDown(object sender, KeyEventArgs e)
    {
        bool ctrlOnly = Keyboard.Modifiers == ModifierKeys.Control;

        // Ctrl+F: open the built-in Find dialog box
        if (ctrlOnly && e.Key == Key.F)
        {
            textControl1.Find();
            e.Handled = true;
        }
        // Ctrl+H: open the built-in Replace dialog box
        else if (ctrlOnly && e.Key == Key.H)
        {
            textControl1.Replace();
            e.Handled = true;
        }
        // Ctrl+A: select the whole text
        else if (ctrlOnly && e.Key == Key.A)
        {
            textControl1.SelectAll();
            e.Handled = true;
        }
        // Insert: switch between inserting and overwriting text
        else if (Keyboard.Modifiers == ModifierKeys.None && e.Key == Key.Insert)
        {
            textControl1.InsertionMode = textControl1.InsertionMode == InsertionMode.Insert
                ? InsertionMode.Overwrite
                : InsertionMode.Insert;
            e.Handled = true;
        }
    }
}

Run the application and press Ctrl+H: the Replace dialog box opens.

The code works as follows:

  • Keyboard.Modifiers of System.Windows.Input returns the modifier keys held down. Comparing it with ModifierKeys.Control accepts Ctrl alone, so that Ctrl+Shift+F doesn't trigger the command. e.Key is the pressed key.
  • Find and Replace without parameters open the built-in dialog boxes. SelectAll selects the whole text.
  • InsertionMode is Insert when typed text is inserted and Overwrite when it replaces the text at the input position.
  • e.Handled = true marks the routed event as handled.

The TX Words sample of the setup handles Ctrl+O, Ctrl+S and Ctrl+P for opening, saving and printing in the same kind of handler. It is installed in %USERPROFILE%\Documents\TX Text Control 34.0.NET for WPF\CSharp\TX Words\Shortcuts.

Insert a Line Break Instead of a Paragraph on Enter

Some applications, such as an editor for address blocks or table captions, need Enter to start a new line inside the same paragraph, the way Shift+Enter does. In code, a line break is the vertical tab character, written "\v" in C#: assigning it to Selection.Text inserts a line break at the input position.

Enter is a key the editor handles itself, and that changes which event you use. WPF raises the tunneling PreviewKeyDown event before the bubbling KeyDown event. According to Microsoft's input overview for WPF, a control that handles a key gets it before the KeyDown handlers of the application, which are called only for keys the control left unhandled; a PreviewKeyDown handler is called first. For keys that have a built-in function, handle PreviewKeyDown, as the handler below does. Connect it in MainWindow.xaml with PreviewKeyDown="TextControl1_PreviewKeyDown" on the TextControl element:

private void TextControl1_PreviewKeyDown(object sender, KeyEventArgs e)
{
    // Enter without modifier keys: insert a line break, not a new paragraph
    if (e.Key == Key.Enter && Keyboard.Modifiers == ModifierKeys.None)
    {
        textControl1.Selection.Text = "\v";
        e.Handled = true;
    }
}

The code works as follows:

  • Key.Enter with ModifierKeys.None limits the change to Enter alone, so Ctrl+Enter still inserts a page break and Ctrl+Shift+Enter a column break.
  • Selection.Text = "\v" replaces the selected text, if there is any, with a line break.
  • e.Handled = true marks the event as handled, so that neither the editor nor a KeyDown handler inserts a paragraph as well.

The old Windows Forms version of this sample used the KeyPress event, which the WPF TextControl does not have. Microsoft describes the order of the keyboard events in the Input Overview of WPF.

Next Steps