# TextControlDocument

> Get the TXPART_Document canvas of the WPF TextControl with Template.FindName or OnApplyTemplate, bind to its size and convert positions with PointToDocument.

- **Product:** TX Text Control .NET for WPF
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for WPF > Integration Guide > Data Binding > TextControlDocument
- **2655 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/data-binding/textcontroldocument/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/data-binding/textcontroldocument/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/data-binding/textcontroldocument/llms-full.txt

---

Inside the template of the WPF `TextControl`, the document is drawn on an element of its own: a `TextControlDocument`, a `Canvas` exactly the size of the document. Code that needs a WPF element for the document, for example to bind another control to its size, finds it here. It is not a data object, though: it holds neither the text nor the formatting, and binding it doesn't bind the content.

### What TextControlDocument Is

The `TextControl` is a `System.Windows.Controls.Control` whose template consists of named parts. Its class declaration lists them with the `TemplatePart` attribute:

| Part | Type | Role |
|---|---|---|
| `TXPART_Border` | `Border` | The border of the control |
| `TXPART_ScrollViewer` | `ScrollViewer` | Shows the visible part of the document |
| `TXPART_Document` | [TextControlDocument](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontroldocument/llms-full.txt) | The document itself |

[TextControlDocument](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontroldocument/llms-full.txt) derives from `System.Windows.Controls.Canvas`. Its size is the size of the whole document, and the `ScrollViewer` around it decides which part of it is on screen. The class was introduced with version 22.0 and has no members of its own: everything it offers comes from `Canvas`, `Panel` and `FrameworkElement`, such as `ActualWidth` and `ActualHeight`.

What the document contains is reached through the `TextControl`, not through this element: [Load](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/load-method/llms-full.txt), [Save](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/save-method/llms-full.txt), [Selection](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/selection-property/llms-full.txt) and the collections of tables, images and fields. [Binding Document Content](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/data-binding/document-content/llms-full.txt) connects the content to a view model.

### Get the Part in Code

A template part exists once WPF has applied the template, which has happened when the `Loaded` event of the control occurs. `Template.FindName` then returns the part by its name. The window in *MainWindow.xaml* has a `TextBlock` below the editor:

```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"
        Title="MainWindow" Height="450" Width="800">
    <DockPanel>
        <TextBlock x:Name="sizeTextBlock" DockPanel.Dock="Bottom" Margin="4" />
        <WPF:TextControl x:Name="textControl1" Loaded="TextControl1_Loaded" />
    </DockPanel>
</Window>
```

The handler in *MainWindow.xaml.cs* finds the document part and binds the `TextBlock` to its height:

```csharp
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using TXTextControl.WPF;

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

        private void TextControl1_Loaded(object sender, RoutedEventArgs e)
        {
            // The template is applied: find the canvas that shows the document
            TextControlDocument document =
                textControl1.Template.FindName("TXPART_Document", textControl1) as TextControlDocument;

            if (document == null)
            {
                return;
            }

            // Show the height of the canvas below the editor
            Binding heightBinding = new Binding("ActualHeight")
            {
                Source = document,
                StringFormat = "Document height: {0:F0} device-independent units"
            };
            sizeTextBlock.SetBinding(TextBlock.TextProperty, heightBinding);
        }
    }
}
```

The code works as follows:

- `Template.FindName` searches the template of `textControl1` for the name `TXPART_Document`. The `as` cast returns `null` if the part isn't there, for example in a template of your own that leaves it out.
- `ActualHeight` is a read-only dependency property of every WPF element, measured in device-independent units of 1/96 inch. A `Binding` with the canvas as its `Source` updates the `TextBlock` whenever the height changes, for example when the text grows by a page.
- The binding is created in code because the part has no name in the scope of the window: `ElementName=TXPART_Document` in XAML doesn't find an element inside the template of another control.

Run the application: the text below the editor shows the height of the document and changes when the document grows or shrinks.

### Get the Part in a Derived Control

A class derived from `TextControl` gets its parts at the moment the template is applied, by overriding `OnApplyTemplate` and calling `GetTemplateChild`:

```csharp
using TXTextControl.WPF;

namespace MyWPFApp
{
    public class DocumentTextControl : TextControl
    {
        // The canvas of the document, available after the template is applied
        public TextControlDocument DocumentPart { get; private set; }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            DocumentPart = GetTemplateChild("TXPART_Document") as TextControlDocument;
        }
    }
}
```

Call `base.OnApplyTemplate()` first, so that the `TextControl` handles its template as before. The derived control is declared in XAML with the prefix of your project's namespace, such as `<local:DocumentTextControl x:Name="textControl1" />` with `xmlns:local="clr-namespace:MyWPFApp"`.

### Positions in the Document

Positions in a document are measured in twips, a twentieth of a point, from its top-left corner. The `TextControl` converts between these document coordinates and its own coordinate system, and reports which part of the document is visible:

| Member | What it does |
|---|---|
| [PointToDocument](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/pointtodocument-method/llms-full.txt) | Converts a `System.Windows.Point` in the coordinate system of the `TextControl` into document coordinates in twips |
| [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 coordinate system of the `TextControl` |
| [ScrollLocation](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/scrolllocation-property/llms-full.txt) | The top-left corner of the visible part, in twips from the top-left corner of the document; available at run time only |
| [VScroll](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/vscroll-event/llms-full.txt), [HScroll](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-wpf/textcontrol/hscroll-event/llms-full.txt) | Occur when the vertical or horizontal scroll position has changed |

Use these members of the `TextControl` for positions in the text rather than the offsets of the `ScrollViewer` part: they are documented in twips, the unit of every other position in TX Text Control. The following handler shows how far the user has scrolled, in inches (1,440 twips each):

```csharp
private void TextControl1_VScroll(object sender, System.EventArgs e)
{
    double inches = textControl1.ScrollLocation.Y / 1440.0;
    sizeTextBlock.Text = $"Scrolled {inches:F1} inches down";
}
```

Connect it with `VScroll="TextControl1_VScroll"` on the `TextControl` element in XAML.

### Replace the Template

The three names are the parts the `TextControl` looks for in its template. No source of Text Control describes a template of your own for the control, so keep the default template and change the look through the properties and styles described in [Styles, Resources, and Themes](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/document-editor/ribbon-ui/themes/llms-full.txt), such as `DisplayColors` for the colors around the pages.

### Next Steps

- [Binding Document Content](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/data-binding/document-content/llms-full.txt): the content and the formatting of the document in bindings.
- [Value Converters](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/data-binding/value-converters/llms-full.txt): twips, colors and zoom factors for WPF controls.
- [Control Initialization and Document Access](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/initialization/llms-full.txt): when the control and its parts are ready.
- [WPF Layout and Resizing](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/layout/llms-full.txt): the size of the `TextControl` in the window.

---

## Nearby

- **Previous:** [Data Binding](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/data-binding/llms-full.txt)
- **Next:** [Binding Document Content](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/integration/data-binding/document-content/llms-full.txt)
