TX Text Control .NET for WPF

Creating and Configuring Controls in Code

Topic

Every element XAML declares can also be created in C#, and TX Text Control is no exception: new TXTextControl.WPF.TextControl() gives you an editor that you add to a panel of the window. Code is the right choice when the window is assembled at run time, for example when editors are added for each opened document or ribbon tabs depend on the user's role. One point needs care: the WPF controls of TX Text Control connect to each other by name, so a control created in code needs a name the editor can find.

The examples go into MainWindow.xaml.cs of a WPF project with the package TXTextControl.TextControl.WPF.SDK, as set up in Create Your First WPF Application. XAML Integration shows the same controls declared in XAML.

Prepare the Window

The window needs a panel for the controls. The following MainWindow.xaml contains only an empty DockPanel named editorPanel:

<Window x:Class="MyWPFApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="450" Width="800">
    <DockPanel x:Name="editorPanel" />
</Window>

The window needs no namespace declaration for TX Text Control, because the XAML contains none of its elements.

Create the Editor and Its Bars

The following constructor creates a button bar, a ruler, a status bar and the editor, connects them and places them in the panel:

using System.Windows;
using System.Windows.Controls;
using TXTextControl;
using TXTextControl.WPF;

namespace MyWPFApp
{
    public partial class MainWindow : Window
    {
        private readonly TXTextControl.WPF.TextControl textControl1;

        public MainWindow()
        {
            InitializeComponent();

            // Create the bars and give each one a name
            ButtonBar buttonBar1 = new ButtonBar() { Name = "buttonBar1" };
            RulerBar rulerBar1 = new RulerBar() { Name = "rulerBar1" };
            TXTextControl.WPF.StatusBar statusBar1 = new TXTextControl.WPF.StatusBar() { Name = "statusBar1" };

            // Register the names in the name scope of the window, as x:Name does
            RegisterName(buttonBar1.Name, buttonBar1);
            RegisterName(rulerBar1.Name, rulerBar1);
            RegisterName(statusBar1.Name, statusBar1);

            // Create the editor and connect the bars by their names
            textControl1 = new TXTextControl.WPF.TextControl()
            {
                Name = "textControl1",
                ButtonBar = "buttonBar1",
                RulerBar = "rulerBar1",
                StatusBar = "statusBar1",
                ViewMode = ViewMode.PageView
            };
            textControl1.Loaded += TextControl1_Loaded;

            // Place the bars at the edges; the editor, added last, fills the rest
            DockPanel.SetDock(buttonBar1, Dock.Top);
            DockPanel.SetDock(rulerBar1, Dock.Top);
            DockPanel.SetDock(statusBar1, Dock.Bottom);
            editorPanel.Children.Add(buttonBar1);
            editorPanel.Children.Add(rulerBar1);
            editorPanel.Children.Add(statusBar1);
            editorPanel.Children.Add(textControl1);
        }

        private void TextControl1_Loaded(object sender, RoutedEventArgs e)
        {
            textControl1.Selection.Text = "Created in code.";
            textControl1.Focus();
        }
    }
}

The code works as follows:

  • The names. The connection properties of the TextControl, such as ButtonBar, RulerBar and StatusBar, hold the name of an existing bar, not the bar. Each bar therefore gets a Name, and RegisterName enters it in the name scope of the window, where XAML enters the names it declares with x:Name.
  • The full class names. TXTextControl.WPF.StatusBar and TXTextControl.WPF.TextControl are written in full. StatusBar is also the name of a WPF class, and the field is declared with its full type to make clear which TextControl is meant.
  • The panel. DockPanel.SetDock sets in code what DockPanel.Dock sets in XAML. The DockPanel places its children in the order they were added, and the last one, the editor, fills the space the bars leave.
  • ViewMode PageView shows the pages like a printed document. The enumeration ViewMode is in the namespace TXTextControl.
  • Loaded. The handler inserts text once WPF has loaded the editor into the window. Members such as Selection are used from there, not from the constructor; see Control Initialization and Document Access.

ButtonBar, RulerBar and StatusBar are described in Connect Rulers, Toolbars, and a Status Bar. Press F5: the window shows the editor with its bars and the inserted sentence.

Add a Ribbon Tab and a Sidebar

The ribbon tabs of TX Text Control go into the Ribbon of WPF, and a Sidebar names its editor. Both work by name in code as they do in XAML:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Ribbon;
using TXTextControl.WPF;

// A WPF ribbon with the Home tab of TX Text Control
RibbonFormattingTab formattingTab = new RibbonFormattingTab() { Name = "ribbonFormattingTab1" };
RegisterName(formattingTab.Name, formattingTab);
Ribbon ribbon1 = new Ribbon();
ribbon1.Items.Add(formattingTab);

// A styles sidebar that names its editor
Sidebar sidebar1 = new Sidebar()
{
    Name = "sidebar1",
    ContentLayout = Sidebar.SidebarContentLayout.Styles,
    TextControl = "textControl1",
    Width = 250
};
RegisterName(sidebar1.Name, sidebar1);

TXTextControl.WPF.TextControl textControl1 = new TXTextControl.WPF.TextControl()
{
    Name = "textControl1",
    RibbonFormattingTab = "ribbonFormattingTab1"
};
RegisterName(textControl1.Name, textControl1);

DockPanel.SetDock(ribbon1, Dock.Top);
DockPanel.SetDock(sidebar1, Dock.Right);
editorPanel.Children.Add(ribbon1);
editorPanel.Children.Add(sidebar1);
editorPanel.Children.Add(textControl1);

The code goes into the constructor after InitializeComponent. It works as follows:

The ribbon tabs are part of the Enterprise and Professional editions; see Editions and Feature Availability.

Change the Connections at Run Time

The connection properties can be changed at any time. An empty string disconnects a bar, and another name connects another one:

// Disconnect the status bar, then hide it
textControl1.StatusBar = string.Empty;
statusBar1.Visibility = Visibility.Collapsed;

A window with several editors uses this to connect one set of bars to the editor the user works with; see Embedding the Editor in Windows and UserControls.

Remove a Control Created in Code

Remove a control from its panel with Children.Remove. When its name was registered, release it with UnregisterName, so that a new control can take the name later:

// Take the editor out of the window and release its name
editorPanel.Children.Remove(textControl1);
UnregisterName(textControl1.Name);

Disconnect the bars and sidebars that named the editor, or remove them as well.

Next Steps