# Search and Replace

> Find and replace text in WPF: built-in dialog boxes, a Replace sidebar in XAML, Find with FindOptions, a Replace All loop with one undo step and all text parts.

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

---

A WPF word processor needs to find text for its users and for its own code: users look for a word or replace a name throughout a contract, and your code fills in placeholders or checks a document for a term. The WPF `TextControl` covers both with built-in Find and Replace dialog boxes, sidebars and a `Find` method that returns the position of a match.

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). The text positions that `Find` returns are explained on [Selections and Caret Position](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/selections/llms-full.txt).

### Find and Replace for Users

With the WPF ribbon, the **Editing** group of the **Home** tab has buttons to find, replace and go to a place in the document, which open dialog boxes or connected sidebars.

In your own buttons and menus, [Find](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/find-method/llms-full.txt) without parameters opens the built-in Find dialog box, and [Replace](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/replace-method/llms-full.txt) the Replace dialog box. The dialog boxes search the main text and, if the user chooses, text frames and headers and footers. The Replace dialog box also offers to match case, to match whole words only and to search upward:

![The Replace dialog box with the Find what and Replace with boxes, the options Match case, Match whole word only, Search up, Search in the main text, Search in text frames and Search in headers and footers, and the Find Next, Replace, Replace All and Cancel buttons.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-wpf/replace-dialog.f462deb4.webp)

The following window has three buttons above the editor. *MainWindow.xaml*:

```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">
    <DockPanel>
        <StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
            <Button Content="Find..." Click="Find_Click" />
            <Button Content="Replace..." Click="Replace_Click" />
            <Button Content="Replace All" Click="ReplaceAll_Click" />
        </StackPanel>
        <WPF:TextControl x:Name="textControl1" Loaded="TextControl1_Loaded" />
    </DockPanel>
</Window>
```

The code-behind comes in the section [Replace All Occurrences](#replace-all-occurrences). The built-in keyboard assignment of the editor doesn't include Ctrl+F or Ctrl+H; [Keyboard Shortcuts](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/keyboard-shortcuts/#add-your-own-shortcuts) shows how to add them.

#### Find and Replace in a Sidebar

A [Sidebar](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/sidebar/llms-full.txt) shows the find and replace functions as a panel beside the document instead of a dialog box. Set its [ContentLayout](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/sidebar/contentlayout-property/llms-full.txt) to `Find` or `Replace` from [SidebarContentLayout](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/sidebar/sidebarcontentlayout-enumeration/llms-full.txt), and set its [TextControl](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/sidebar/textcontrol-property/llms-full.txt) property to the name of the editor:

```xml
<DockPanel>
    <WPF:Sidebar x:Name="replaceSidebar" DockPanel.Dock="Right" HorizontalAlignment="Right" Width="250"
                ContentLayout="Replace" TextControl="textControl1" />
    <WPF:TextControl x:Name="textControl1" />
</DockPanel>
```

A sidebar aligned to the left or right edge arranges its content vertically, one aligned to the top or bottom horizontally. To have the ribbon buttons open your sidebars, set [FindSidebar](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/ribbonformattingtab/findsidebar-property/llms-full.txt) and [ReplaceSidebar](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/ribbonformattingtab/replacesidebar-property/llms-full.txt) of the [RibbonFormattingTab](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/ribbonformattingtab/llms-full.txt) to the names of vertical sidebars, and `FindHorizontalSidebar` and `ReplaceHorizontalSidebar` to horizontal ones. [Sidebar and Panels](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/ribbon-ui/sidebar/llms-full.txt) covers the setup.

### Find Text in Code

Two overloads of `Find` search without a dialog box and return a zero-based text position:

| Overload | Searches |
|---|---|
| `Find(string text)` | From the beginning of the text |
| `Find(string text, int start, FindOptions options)` | From `start`, or from the input position if `start` is -1, with the given options |

The return value is the position of the first character of the match, or -1 if nothing is found. The search covers the text part with the input focus: the main text, or a header, footer or text frame the user is editing.

[FindOptions](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/findoptions/enumeration/llms-full.txt) values are combined with `|`:

| Value | Effect |
|---|---|
| `MatchCase` | Finds only matches with the same uppercase and lowercase letters |
| `MatchWholeWord` | Finds only whole words |
| `Reverse` | Searches from the end of the document toward the beginning |
| `NoHighlight` | Doesn't highlight the match |
| `NoMessageBox` | Doesn't show message boxes about the search result |

Set `NoMessageBox` whenever your code searches on its own, so that no message box interrupts it.

### Replace All Occurrences

*MainWindow.xaml.cs* for the window above writes a sentence into the editor when it is loaded. **Replace All** replaces every "order" with "purchase", and the other two buttons open the dialog boxes. Replace `SampleApp` with the namespace of your project:

```csharp
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.";
    }

    // Open the built-in dialog boxes
    private void Find_Click(object sender, RoutedEventArgs e) => textControl1.Find();

    private void Replace_Click(object sender, RoutedEventArgs e) => textControl1.Replace();

    private void ReplaceAll_Click(object sender, RoutedEventArgs e)
    {
        int count = ReplaceAll("order", "purchase");
        MessageBox.Show(this, count + " replacements");
    }

    private int ReplaceAll(string searchText, string replacementText)
    {
        FindOptions options = FindOptions.MatchWholeWord | FindOptions.NoMessageBox;
        int count = 0;

        // All replacements are undone in one step
        textControl1.BeginUndoAction("Replace All");

        try
        {
            int position = textControl1.Find(searchText, 0, options);

            while (position != -1)
            {
                textControl1.Select(position, searchText.Length);
                textControl1.Selection.Text = replacementText;
                count++;

                // Continue behind the inserted text
                position = textControl1.Find(searchText, position + replacementText.Length, options);
            }
        }
        finally
        {
            textControl1.EndUndoAction();
        }

        return count;
    }
}
```

Click **Replace All**: a message box reports 2 replacements, and the text reads "Invoice for purchase 1234. Thank you for your purchase."

The code works as follows:

- `MatchWholeWord` keeps "order" from matching inside words such as "orders", and `NoMessageBox` keeps the search silent.
- [Select](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/select-method/llms-full.txt) selects each match, and [Selection.Text](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/selection/text-property/llms-full.txt) replaces it.
- The next search starts behind the inserted text, so a replacement that contains the search text is not found again.
- [BeginUndoAction](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/beginundoaction-method/llms-full.txt) and [EndUndoAction](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/endundoaction-method/llms-full.txt) turn all replacements into one step that Ctrl+Z undoes at once. See [Undo and Redo](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/undo-redo/llms-full.txt).

### Search Headers, Footers and Text Frames

To search all parts of a document regardless of the input focus, loop through [TextParts](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/textparts-property/llms-full.txt). It contains the main text, the headers and footers and the text frames, each an [IFormattedText](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/iformattedtext/llms-full.txt) object with its own [Find](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/iformattedtext/find-method/llms-full.txt) and [Selection](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/iformattedtext/selection-property/llms-full.txt).

The following method, added to *MainWindow.xaml.cs*, gives every occurrence of a text a yellow background:

```csharp
private void HighlightEverywhere(string searchText)
{
    foreach (IFormattedText textPart in textControl1.TextParts)
    {
        int position = textPart.Find(searchText, 0, FindOptions.NoMessageBox);

        while (position != -1)
        {
            textPart.Selection = new Selection(position, searchText.Length) { TextBackColor = System.Drawing.Color.Yellow };
            position = textPart.Find(searchText, position + searchText.Length, FindOptions.NoMessageBox);
        }
    }
}
```

[TextBackColor](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/selection/textbackcolor-property/llms-full.txt) of the shared `Selection` class is a `System.Drawing.Color`, also in a WPF application, so the color is written with its full name.

### Search With Regular Expressions

`Find` searches for literal text. For patterns such as dates or email addresses, apply a .NET regular expression to the text and select the matches by their positions, as the blog article [Advanced Smart Search with Regular Expressions in .NET C#](https://www.textcontrol.com/blog/2025/01/29/advanced-smart-search-with-regular-expressions-in-net-csharp/) shows.

### Next Steps

- [Undo and Redo](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/undo-redo/llms-full.txt): group changes into one undo step.
- [Keyboard Shortcuts](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/keyboard-shortcuts/llms-full.txt): assign Ctrl+F and Ctrl+H.
- [Built-in Dialog Boxes](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/ribbon-ui/dialog-boxes/llms-full.txt): the other dialog boxes of the editor.
- [Fields, Hyperlinks, and Bookmarks](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/fields/llms-full.txt): mark text that your code replaces later, instead of searching for it.

---

## Nearby

- **Previous:** [Undo and Redo](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/undo-redo/llms-full.txt)
- **Next:** [Drag and Drop](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/editing-text/drag-drop/llms-full.txt)
