# Selections and Caret Position

> Use Select, Selection and InputPosition in a WPF TextControl to select and replace text, follow the caret and find lines and characters with their bounds.

- **Product:** TX Text Control .NET for WPF
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for WPF > Document Editor > Editing Text > Selections and Caret Position
- **5958 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/selections/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/selections/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/selections/llms-full.txt

---

Where is the user typing, and which text will the next command change? In a WPF `TextControl`, the answer is always the input position or the selection. Your code reads them to react to the user and sets them to insert, replace or format text at a known place in the document.

The examples use a window with a `TextControl` named `textControl1`, as in [Create Your First WPF Application](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/getting-started/document-editor/first-application/llms-full.txt). Formatting the selected text is covered on [Text and Paragraph Formatting](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/formatting/llms-full.txt).

### Text Positions and the Input Position

Characters are counted from 0: text position 0 lies in front of the first character, and a selection with the start 18 and the length 4 covers the 19th to the 22nd character. [Select](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/select-method/llms-full.txt), the [Selection](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/selection/llms-full.txt) class and [Find](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/find-method/llms-full.txt) all use these numbers.

The *input position* is where typed text appears, marked by the caret. Without selected text, the selection has a length of 0, and its start is the input position. With selected text, typing replaces it.

The `TextControl` of the `TXTextControl.WPF` namespace has two properties for this:

- [Selection](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/selection-property/llms-full.txt) returns a `Selection` object for the current selection, and accepts a new one.
- [InputPosition](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/inputposition-property/llms-full.txt) returns an [InputPosition](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/inputposition/llms-full.txt) object with the page, line and column of the caret, and accepts a new one to move it.

`Selection` and `InputPosition` are classes of the `TXTextControl` namespace, the same as in the Windows Forms product. Both refer to the text part with the input focus, which is the main text, a text frame, or a header or footer.

### Select Text With the Mouse and Keyboard

Users select text without any code in your application:

| Mouse action | Result |
|---|---|
| Click | Moves the caret to the point of the click, or selects an image or a text frame |
| Click and drag | Selects the text between the points where the button is pressed and released |
| Shift+click | Extends the selection to the point of the click |
| Double-click | Selects the word |
| Double-click and drag | Extends the selection word by word |
| Triple-click | Selects the paragraph |
| Triple-click and drag | Extends the selection paragraph by paragraph |
| Click in the left or right margin | Selects the line |

In tables, a click on the top of a column selects the column, a click in the margin next to a row selects the row, and a double-click selects a cell. Every key that moves the caret extends the selection while Shift is held down. All keys are listed on [Keyboard Shortcuts](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/keyboard-shortcuts/llms-full.txt).

### Select and Replace Text in Code

[Select](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/select-method/llms-full.txt) selects a number of characters from a start position, [SelectAll](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/selectall-method/llms-full.txt) the whole text and [SelectWord](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/selectword-method/llms-full.txt) the word at the input position. [Selection.Text](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/selection/text-property/llms-full.txt) then returns the selected text, and setting it replaces the selection.

The control can be used once its `Loaded` event has occurred. In *MainWindow.xaml*, connect the event handlers of this page to the control:

```xml
<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"
                        Loaded="TextControl1_Loaded"
                        InputPositionChanged="TextControl1_InputPositionChanged" />
    </Grid>
</Window>
```

Replace `SampleApp` with the namespace of your project. The `Loaded` handler in *MainWindow.xaml.cs* writes a sentence into the editor, reads and replaces the order number and formats the first word:

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

namespace SampleApp;

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

    private void TextControl1_Loaded(object sender, RoutedEventArgs e)
    {
        textControl1.Text = "Invoice for order 1234. Thank you for your order.";

        // Select the four characters "1234", which start at text position 18
        textControl1.Select(18, 4);
        string orderNumber = textControl1.Selection.Text;

        // Replace the selected text
        textControl1.Selection.Text = "5678";

        // Format "Invoice" with a prepared Selection object
        Selection title = new Selection(0, 7);
        title.Bold = true;
        title.Italic = true;
        textControl1.Selection = title;

        // Move the input position to the start of the text
        textControl1.InputPosition = new InputPosition(0);
        textControl1.Focus();
    }

    private void TextControl1_InputPositionChanged(object sender, EventArgs e)
    {
        InputPosition position = textControl1.InputPosition;

        Title = $"Page {position.Page}, line {position.Line}, column {position.Column}, " +
            $"text position {position.TextPosition}, selected: {textControl1.Selection.Length}";
    }
}
```

Run the application: the editor shows "*Invoice* for order 5678. Thank you for your order.", and the title bar of the window follows the caret as you click and type.

The code works as follows:

- [Text](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/text-property/llms-full.txt) replaces the whole content with plain text.
- `Select(18, 4)` selects "1234". `Selection.Text` reads it and then replaces it with "5678".
- `new Selection(0, 7)` creates a [Selection](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/selection/constructor/llms-full.txt) object for the first seven characters. Its properties, such as [Bold](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/selection/bold-property/llms-full.txt), are applied to that range when the object is assigned to `textControl1.Selection`.
- [new InputPosition(0)](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/inputposition/constructor/llms-full.txt) puts the caret in front of the first character.
- [InputPositionChanged](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/inputpositionchanged-event/llms-full.txt) occurs whenever the caret moves, whether by typing, a click or code. The handler writes the position into the `Title` of the window.

#### Prepare a Selection Object or Change the Current Selection

Text is changed either by selecting it with `Select` and setting the properties of `textControl1.Selection` one by one, or by preparing a `Selection` object and assigning it once, as the code does for "Invoice".

The prepared object doesn't show a visible selection while it is applied, and it counts as a single step for [Undo and Redo](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/undo-redo/llms-full.txt). Each property set on the current selection is a step of its own. The `Selection` constructor without parameters creates an object whose `Text` and formatting are inserted at the input position when you assign it.

#### Selection Properties

| Property | Contains |
|---|---|
| [Start](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/selection/start-property/llms-full.txt) | The text position where the selection begins, starting with 0. Setting it keeps the current length. |
| [Length](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/selection/length-property/llms-full.txt) | The number of selected characters. With 0, `Start` is the input position. A start of 0 and a length of `int.MaxValue` select the whole text. |
| [Text](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/selection/text-property/llms-full.txt) | The selected text as a string. Setting it replaces the selection. |

When the selected text has different values for an attribute, for example partly bold text, the property returns its default value, and [IsCommonValueSelected](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/selection/iscommonvalueselected-method/llms-full.txt) returns `false` for that attribute.

To exchange the selection as formatted text, [Selection.Save](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/selection/save-method/llms-full.txt) writes it to a file, a byte array or a string in a format such as HTML, RTF or DOCX, and [Selection.Load](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/selection/load-method/llms-full.txt) replaces it with formatted content:

```csharp
// Get the selected text as HTML
string html;
textControl1.Selection.Save(out html, StringStreamType.HTMLFormat);

// Replace the selection with formatted text
textControl1.Selection.Load("<p>Paid in <strong>full</strong></p>", StringStreamType.HTMLFormat);
```

### Move the Input Position

The `InputPosition` object describes the caret:

| Property | Contains |
|---|---|
| [Page](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/inputposition/page-property/llms-full.txt) | The page number, only when [ViewMode](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/viewmode-property/llms-full.txt) is `ViewMode.PageView` |
| [Line](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/inputposition/line-property/llms-full.txt) | The line on the page, starting with 1 |
| [Column](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/inputposition/column-property/llms-full.txt) | The column in the line, starting with 0 in front of the first character |
| [TextPosition](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/inputposition/textposition-property/llms-full.txt) | The text position, starting with 0 |
| [Section](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/inputposition/section-property/llms-full.txt) | The section, starting with 1 |
| [PageInSection](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/inputposition/pageinsection-property/llms-full.txt) | The page number within the section, only in `ViewMode.PageView` |
| [Location](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/inputposition/location-property/llms-full.txt) | The position of the caret in twips, from the top-left corner of the document |
| [CaretSize](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/inputposition/caretsize-property/llms-full.txt) | The size of the caret at the input position, in pixels |

Except for `InactiveMarker`, the properties are read-only; to move the caret, assign a new object. The [InputPosition constructor](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/inputposition/constructor/llms-full.txt) takes a text position, or a page, a line and a column. For a text position at the start or end of a field, a value of [TextFieldPosition](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/textfieldposition/enumeration/llms-full.txt) decides whether the caret lies inside or outside the field.

```csharp
// Move the caret to page 1, line 1, column 0
textControl1.InputPosition = new InputPosition(1, 1, 0);

// Scroll the caret to the top of the visible area
textControl1.InputPosition.ScrollTo(InputPosition.ScrollPosition.Top);
```

[ScrollTo](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/inputposition/scrollto-method/llms-full.txt) scrolls the caret into view. Without a parameter, it chooses the position itself.

[InactiveMarker](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/inputposition/inactivemarker-property/llms-full.txt) is the one property that can be set: with `true`, a marker shows the input position while the editor is inactive and the blinking caret isn't visible.

### Read Text Without Selecting It

To read text without moving the caret or the visible selection, use the collections of the `TextControl`:

```csharp
// The paragraph at the input position
string paragraphText = textControl1.Paragraphs.GetItem(textControl1.InputPosition.TextPosition).Text;

// The first line of the document
string firstLine = textControl1.Lines[1].Text;

// The fifth character
char fifthCharacter = textControl1.TextChars[5].Char;
```

- [Paragraphs](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/paragraphs-property/llms-full.txt) contains the paragraphs. [GetItem](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/paragraphcollection/getitem-method/llms-full.txt) returns the paragraph at a text position, and [Text](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/paragraph/text-property/llms-full.txt) its text.
- [Lines](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/lines-property/llms-full.txt) contains the lines, numbered from 1.
- [TextChars](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/textchars-property/llms-full.txt) contains the characters, numbered from 1.

### Find Lines and Characters on the Screen

Each formatted line and each character also has a position on the page. The [Line](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/line/llms-full.txt) and [TextChar](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/textchar/llms-full.txt) objects of the `Lines` and `TextChars` collections report it, for example to place a WPF element next to a line or to show a tooltip for the word under the mouse pointer. Their measures are in twips, 1,440 to the inch, from the top-left corner of the whole document.

The following handler of a button with `Click="ShowLine_Click"` describes the line with the caret in the title bar and gets the line as HTML:

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

private void ShowLine_Click(object sender, RoutedEventArgs e)
{
    // GetItem takes a zero-based text position
    TXTextControl.Line line = textControl1.Lines.GetItem(textControl1.InputPosition.TextPosition);

    // Bounds and baseline in twips, relative to the document
    System.Drawing.Rectangle bounds = line.TextBounds;

    // The same point in the coordinates of the control
    Point topLeft = textControl1.PointFromDocument(new Point(bounds.Left, bounds.Top));

    // The text of the line as HTML
    string html;
    line.Save(out html, StringStreamType.HTMLFormat);

    Title = $"Line {line.Number} on page {line.Page}, {bounds.Width} twips wide, " +
        $"baseline at {line.Baseline} twips, shown at {topLeft.X:0}, {topLeft.Y:0}";
}
```

The code works as follows:

- [LineCollection.GetItem](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/linecollection/getitem-method/llms-full.txt) returns the line at a zero-based text position, or at a point of the control. It returns `null` if there is no line there.
- [TextBounds](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/line/textbounds-property/llms-full.txt) is the rectangle around the text of the line and [Baseline](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/line/baseline-property/llms-full.txt) the vertical position of its baseline. [Number](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/line/number-property/llms-full.txt), [Page](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/line/page-property/llms-full.txt), [Start](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/line/start-property/llms-full.txt) and [Length](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/line/length-property/llms-full.txt) give the place of the line in the text; `Start` counts from 1.
- [PointFromDocument](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/pointfromdocument-method/llms-full.txt) converts a point in document coordinates into the coordinates of the `TextControl`. [PointToDocument](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/pointtodocument-method/llms-full.txt) converts the other way, and [ScrollLocation](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/scrolllocation-property/llms-full.txt) is the top-left corner of the visible part of the document.
- [Line.Save](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/line/save-method/llms-full.txt) saves the text of the line to a string or a byte array in a format such as HTML or RTF.

`TXTextControl.Line` is written with its namespace because `System.Windows.Shapes`, which the WPF project template imports, has a `Line` class too.

#### Find the Character Under the Mouse Pointer

[TextCharCollection.GetItem](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/textcharcollection/getitem-method/llms-full.txt) returns the character at a point of the control. Connect `PreviewMouseMove="TextControl1_PreviewMouseMove"` to the `TextControl` in *MainWindow.xaml* and add this handler:

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

private void TextControl1_PreviewMouseMove(object sender, MouseEventArgs e)
{
    Point mouse = e.GetPosition(textControl1);

    // false: only a character whose bounds contain the point
    TextChar character = textControl1.TextChars.GetItem(
        new System.Drawing.Point((int)mouse.X, (int)mouse.Y), false);

    if (character != null)
    {
        Title = $"Character {character.Number}: '{character.Char}', bounds {character.Bounds}";
    }
}
```

The point is given in pixels from the top-left corner of the control. `GetPosition` returns WPF's device-independent units, which match pixels at a display scaling of 100 percent; [DPI and Display Scaling](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/dpi-scaling/llms-full.txt) covers other settings. With `true` as the second parameter, `GetItem` returns the nearest character instead of `null`. [Bounds](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/textchar/bounds-property/llms-full.txt) is the rectangle of the character in twips, relative to the document, and [Number](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/textchar/number-property/llms-full.txt) its position, starting with 1.

[TextCharCollection.Add](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/textcharcollection/add-method/llms-full.txt) inserts a single character or a control character at the input position or at a text position, and [TextCharCollection.Remove](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/textcharcollection/remove-method/llms-full.txt) removes one; control characters that other formatting depends on, such as the end of a table cell, can't be removed. The [LineCollection](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/linecollection/llms-full.txt) and [TextCharCollection](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/textcharcollection/llms-full.txt) of headers, footers and text frames work the same way.

### Select Tables and Objects

Tables are selected by their parts: [Table.Select](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/table/select-method/llms-full.txt), [TableRow.Select](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablerow/select-method/llms-full.txt), [TableColumn.Select](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecolumn/select-method/llms-full.txt) and [TableCell.Select](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/tablecell/select-method/llms-full.txt). See [Tables and Table Formulas](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/tables/llms-full.txt).

For objects placed behind the text, [SelectObjects](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/selectobjects-property/llms-full.txt) decides what a click selects: with `true`, the object; with `false`, the text in front of it.

### Change How the Selection and the Caret Look

| Property | Effect |
|---|---|
| [HideSelection](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/hideselection-property/llms-full.txt) | Whether the selected text stays highlighted when the editor loses the keyboard focus |
| [SelectionViewMode](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/selectionviewmode-property/llms-full.txt) | `TransparentBitmap` shows the selection with a transparent highlight, `Classic` inverts the selected text |
| [CaretWidth](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/caretwidth-property/llms-full.txt) | The width of the caret in pixels, up to 255; 0 uses the system default |

All three can be set as attributes in XAML, for example `HideSelection="False"`.

### Next Steps

- [Clipboard Operations](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/clipboard/llms-full.txt): copy, cut and paste the selection.
- [Search and Replace](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/search-replace/llms-full.txt): find text and select each match.
- [Text and Paragraph Formatting](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/formatting/llms-full.txt): format the selection.
- [Events](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/events/llms-full.txt): the other events of the editor.

---

## Nearby

- **Previous:** [Editing Text](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/llms-full.txt)
- **Next:** [Clipboard Operations](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/clipboard/llms-full.txt)
