# Commands and Input Bindings

> Connect WPF menus, toolbars and KeyBinding to the TextControl with RoutedUICommand and CommandBinding, using CanCopy, CanUndo and CanPrint for CanExecute.

- **Product:** TX Text Control .NET for WPF
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for WPF > Integration Guide > Commands and Input Bindings
- **5890 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/commands/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/commands/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/commands/llms-full.txt

---

WPF separates what a menu item or button does from the control that triggers it: a command names the action, a command binding says what happens, and an input binding gives the action a key. The reference documents no commands of the `TextControl`, so the command bindings of your window call its methods, such as `Copy`, `Undo` or `Print`, and ask its `Can...` properties whether a command is available. The window built below has a menu, a toolbar and key bindings that all run through commands.

### How Commands Reach the Editor

| Part | What it does | Where it goes |
|---|---|---|
| `RoutedUICommand` | Names an action, with a text and optional key gestures | A static class, or the predefined `ApplicationCommands` |
| `CommandBinding` | Connects a command to an `Executed` handler and a `CanExecute` handler | `Window.CommandBindings` |
| `KeyBinding` | Connects a key to a command | `Window.InputBindings` |
| `Command` property | Triggers the command | `MenuItem`, `Button` and other controls |

A routed command travels from the element with the keyboard focus, usually the `TextControl`, up to the window, where the command binding handles it. `CanExecute` is asked again whenever the input changes, and WPF disables every menu item and button of a command that can't execute.

The editor handles some keys itself: Ctrl+C, Ctrl+X, Ctrl+V, Ctrl+Z, Ctrl+Y and the others listed in [Keyboard Shortcuts](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/keyboard-shortcuts/llms-full.txt). The commands for these actions below have no key gesture, and their menu items show the key with `InputGestureText` only. Keys the editor doesn't use, such as Ctrl+O, Ctrl+S, Ctrl+P or Ctrl+B, can belong to your commands.

### Define the Commands

`ApplicationCommands` of WPF already defines **Open**, **Save** and **Print** with the keys Ctrl+O, Ctrl+S and Ctrl+P. The other commands go into a class of your own, *EditorCommands.cs*:

```csharp
using System.Windows.Input;

namespace MyWPFApp
{
    public static class EditorCommands
    {
        // Ctrl+B is not a built-in key of the editor, so the command can own it
        public static readonly RoutedUICommand Bold = new RoutedUICommand(
            "Bold", "Bold", typeof(EditorCommands),
            new InputGestureCollection { new KeyGesture(Key.B, ModifierKeys.Control) });

        public static readonly RoutedUICommand InsertDate = new RoutedUICommand(
            "Insert Date", "InsertDate", typeof(EditorCommands));

        // The editor handles Ctrl+C, Ctrl+X, Ctrl+V, Ctrl+Z and Ctrl+Y itself,
        // so these commands get no key gesture
        public static readonly RoutedUICommand Cut = new RoutedUICommand("Cut", "Cut", typeof(EditorCommands));
        public static readonly RoutedUICommand Copy = new RoutedUICommand("Copy", "Copy", typeof(EditorCommands));
        public static readonly RoutedUICommand Paste = new RoutedUICommand("Paste", "Paste", typeof(EditorCommands));
        public static readonly RoutedUICommand Undo = new RoutedUICommand("Undo", "Undo", typeof(EditorCommands));
        public static readonly RoutedUICommand Redo = new RoutedUICommand("Redo", "Redo", typeof(EditorCommands));
    }
}
```

### Bind the Commands in XAML

*MainWindow.xaml* binds each command to its handlers, gives **Insert Date** the key F5 and uses the commands in a menu and a toolbar:

```xml
<Window x:Class="MyWPFApp.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"
        xmlns:local="clr-namespace:MyWPFApp"
        Title="MainWindow" Height="450" Width="800">
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Open" Executed="Open_Executed" />
        <CommandBinding Command="ApplicationCommands.Save" Executed="Save_Executed" />
        <CommandBinding Command="ApplicationCommands.Print"
                        Executed="Print_Executed" CanExecute="Print_CanExecute" />
        <CommandBinding Command="local:EditorCommands.Cut"
                        Executed="Cut_Executed" CanExecute="Copy_CanExecute" />
        <CommandBinding Command="local:EditorCommands.Copy"
                        Executed="Copy_Executed" CanExecute="Copy_CanExecute" />
        <CommandBinding Command="local:EditorCommands.Paste"
                        Executed="Paste_Executed" CanExecute="Paste_CanExecute" />
        <CommandBinding Command="local:EditorCommands.Undo"
                        Executed="Undo_Executed" CanExecute="Undo_CanExecute" />
        <CommandBinding Command="local:EditorCommands.Redo"
                        Executed="Redo_Executed" CanExecute="Redo_CanExecute" />
        <CommandBinding Command="local:EditorCommands.Bold" Executed="Bold_Executed" />
        <CommandBinding Command="local:EditorCommands.InsertDate" Executed="InsertDate_Executed" />
    </Window.CommandBindings>
    <Window.InputBindings>
        <KeyBinding Key="F5" Command="local:EditorCommands.InsertDate" />
    </Window.InputBindings>
    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_File">
                <MenuItem Command="ApplicationCommands.Open" />
                <MenuItem Command="ApplicationCommands.Save" />
                <MenuItem Command="ApplicationCommands.Print" />
            </MenuItem>
            <MenuItem Header="_Edit">
                <MenuItem Command="local:EditorCommands.Undo" InputGestureText="Ctrl+Z" />
                <MenuItem Command="local:EditorCommands.Redo" InputGestureText="Ctrl+Y" />
                <Separator />
                <MenuItem Command="local:EditorCommands.Cut" InputGestureText="Ctrl+X" />
                <MenuItem Command="local:EditorCommands.Copy" InputGestureText="Ctrl+C" />
                <MenuItem Command="local:EditorCommands.Paste" InputGestureText="Ctrl+V" />
            </MenuItem>
            <MenuItem Header="F_ormat">
                <MenuItem Command="local:EditorCommands.Bold" />
                <MenuItem Command="local:EditorCommands.InsertDate" InputGestureText="F5" />
            </MenuItem>
        </Menu>
        <ToolBar DockPanel.Dock="Top">
            <Button Content="Save" Command="ApplicationCommands.Save" />
            <Button Content="Undo" Command="local:EditorCommands.Undo" />
            <Button Content="Bold" Command="local:EditorCommands.Bold" />
        </ToolBar>
        <WPF:TextControl x:Name="textControl1" />
    </DockPanel>
</Window>
```

A `MenuItem` with a `RoutedUICommand` and no `Header` shows the text of the command, and for a command with a key gesture, such as **Bold**, the key as well.

### Write the Handlers

The handlers in *MainWindow.xaml.cs* call the methods of the editor:

```csharp
using System;
using System.Windows;
using System.Windows.Input;
using TXTextControl;

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

        private void Open_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            // The built-in Open dialog box; the enumeration is written in full
            // because Window has a DialogResult property of its own
            if (textControl1.Load() == TXTextControl.WPF.DialogResult.OK)
            {
                Title = "Document opened";
            }
        }

        private void Save_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            textControl1.Save(StreamType.WordprocessingML);
        }

        private void Print_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = textControl1.CanPrint;
        }

        private void Print_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            textControl1.Print("Document", true);
        }

        private void Copy_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = textControl1.CanCopy;
        }

        private void Cut_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            textControl1.Cut();
        }

        private void Copy_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            textControl1.Copy();
        }

        private void Paste_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = textControl1.CanPaste;
        }

        private void Paste_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            textControl1.Paste();
        }

        private void Undo_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = textControl1.CanUndo;
        }

        private void Undo_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            textControl1.Undo();
        }

        private void Redo_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = textControl1.CanRedo;
        }

        private void Redo_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            textControl1.Redo();
        }

        private void Bold_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            textControl1.Selection.Bold = !textControl1.Selection.Bold;
        }

        private void InsertDate_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            textControl1.Selection.Text = DateTime.Today.ToLongDateString();
        }
    }
}
```

The code works as follows:

- [Load](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/load-method/llms-full.txt) without parameters opens the built-in **Open** dialog box and returns a [DialogResult](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/dialogresult/enumeration/llms-full.txt) of the namespace `TXTextControl.WPF`. Inside a `Window`, the name `DialogResult` alone means the property of the window, so the enumeration is written with its namespace.
- [Save](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/save-method/llms-full.txt) with a [StreamType](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/streamtype/enumeration/llms-full.txt) opens the **Save As** dialog box, which offers the file format filters of the given stream type, here DOCX. [Load and Save Documents](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/getting-started/document-editor/load-save/llms-full.txt) adds the current file and a save-changes prompt.
- [Print](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/print-method/llms-full.txt) opens the print dialog box; `true` starts it with the settings of the previous call. [CanPrint](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/canprint-property/llms-full.txt) depends on the document permissions and the edit mode.
- [CanCopy](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/cancopy-property/llms-full.txt), [CanPaste](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/canpaste-property/llms-full.txt), [CanUndo](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/canundo-property/llms-full.txt) and [CanRedo](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/canredo-property/llms-full.txt) answer the `CanExecute` questions, and [Cut](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/cut-method/llms-full.txt), [Copy](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/copy-method/llms-full.txt), [Paste](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/paste-method/llms-full.txt), [Undo](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/undo-method/llms-full.txt) and [Redo](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/redo-method/llms-full.txt) do the work.
- [Selection](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/selection-property/llms-full.txt) is the selected text or the input position. Toggling [Bold](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/selection/bold-property/llms-full.txt) formats it, and setting `Text` inserts the date there.

Run the application and select a word: **Cut** and **Copy** become available in the menu. Press Ctrl+B to make it bold, and F5 to insert today's date.

### Commands From a View Model

In an MVVM application, the commands are `ICommand` properties of the view model, bound with `Command="{Binding SaveCommand}"`, and a `KeyBinding` can bind to them as well:

```xml
<Window.InputBindings>
    <KeyBinding Key="S" Modifiers="Control" Command="{Binding SaveCommand}" />
</Window.InputBindings>
```

The view model can't call `textControl1` directly. [MVVM Integration Patterns](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/mvvm/llms-full.txt) shows how its commands reach the editor through bindings and an interface that the window implements.

### Keys Only While the Editor Has the Focus

Key bindings of the window work wherever the focus is in the window. A key that should act only while the user types in the document is handled in the `KeyDown` event of the `TextControl` instead, as [Keyboard Shortcuts](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/keyboard-shortcuts/#add-your-own-shortcuts) shows with Ctrl+F and Ctrl+H. The TX Words sample *Shortcuts* of the setup uses the same event for Ctrl+O, Ctrl+S and Ctrl+P.

### Next Steps

- [MVVM Integration Patterns](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/mvvm/llms-full.txt): commands in a view model.
- [Clipboard Operations](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/clipboard/llms-full.txt): what `Cut`, `Copy` and `Paste` transfer.
- [Undo and Redo](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/undo-redo/llms-full.txt): the undo history and grouped actions.
- [Custom Tabs and Commands](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/ribbon-ui/custom-tabs/llms-full.txt): commands in the ribbon.

---

## Nearby

- **Previous:** [MVVM Integration Patterns](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/mvvm/llms-full.txt)
- **Next:** [WPF Layout and Resizing](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/layout/llms-full.txt)
