Creating and Configuring Controls in Code
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, andRegisterNameenters it in the name scope of the window, where XAML enters the names it declares withx:Name. - The full class names.
TXTextControl.WPF.StatusBarandTXTextControl.WPF.TextControlare written in full.StatusBaris also the name of a WPF class, and the field is declared with its full type to make clear whichTextControlis meant. - The panel.
DockPanel.SetDocksets in code whatDockPanel.Docksets in XAML. TheDockPanelplaces its children in the order they were added, and the last one, the editor, fills the space the bars leave. - ViewMode
PageViewshows the pages like a printed document. The enumerationViewModeis in the namespaceTXTextControl. 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:
Ribbonis the ribbon of WPF, inSystem.Windows.Controls.Ribbon; itsItemscollection takes the tabs. The RibbonFormattingTab is the Home tab of TX Text Control, and TextControl.RibbonFormattingTab connects it by name. The other predefined tabs have properties of their own; Connecting Ribbon Tabs in XAML lists them.- ContentLayout chooses the panel of the sidebar, and Sidebar.TextControl holds the name of the editor, so the editor gets a registered name as well.
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
- XAML Integration: the same controls declared in XAML.
- Embedding the Editor in Windows and UserControls: the editor in a user control and several editors in one window.
- Control Initialization and Document Access: when the members of the editor can be used.
- Custom Tabs and Commands: ribbon tabs and buttons of your own, created in code.