This sample shows how to combine all components provided by TX Text Control to create a ribbon application.
Furthermore, it implements code that gives the items of the application menu the behavior to reset the content, open a document, save and print it, determine its settings and exit the application. It also implements a file management and provides a list of recent files.
Besides the implementation of an application menu, the sample manages the layout of the quick access toolbar, sidebars, ruler and status bars, the contextual tabs management and updating the custom button images when changing the resolution.
The source code for this example is contained in the following directories:
When creating the sample with the Visual Studio designer, after adding a TextControl to the form, the following controls were additionally added to the form by using the TextControl smart tag:
All of these controls were arranged by clicking the Arrange Controls Automatically smart tag item.
The following predefined ribbon tabs were added to the ribbon by using the smart tag:
The buttons of the application menu were implemented by opening the Control Collection Editor when clicking the corresponding button of the ApplicationMenuItems property inside the Properties window for the ribbon control.
By clicking the Ribbon.ContextualTabGroups property button, a Control Collection Editor is opened in order to create two objects of type ContextualTabGroup . To the first one, a Table Layout (type of RibbonTableLayoutTab) and a Formulas tab (type of RibbonFormulaTab) are added by editing the ContextualTabs property via the Properties window. To the second one, a Frame Formatting (type of RibbonFrameLayoutTab) and a Chart Layout tab (type of RibbonChartLayoutTab) were added.
To show the About sidebar on starting the application, its ContentLayout property is set to About by selecting the corresponding drop down item inside the left sidebar's smart tag. To prevent an unpinning of the sidebar, the smart tag's ShowPinButton check box is unchecked.
Both other sidebars are hidden when running the sample. This was implemented by unchecking the smart tag's IsShown check box.
All sidebars were connected to predefined ribbon tabs to show a specific layout and perform the corresponding behavior when the related button is clicked. The connection can be set by the Properties window or the smart tag of the ribbon tab. For this sample, the predefined ribbon tabs are associated with the sidebars as follows:
The Home tab:
Property | Sidebar |
---|---|
Find |
bottom |
Find |
right |
Goto |
bottom |
Goto |
(none) |
Replace |
bottom |
Replace |
right |
Styles |
right |
The Proofing tab:
Property | Sidebar |
---|---|
Comments |
bottom |
Comments |
right |
Tracked |
bottom |
Tracked |
right |
The Form Fields tab:
Property | Sidebar |
---|---|
Conditional |
bottom |
Conditional |
right |
The Reporting tab:
Property | Sidebar |
---|---|
Field |
bottom |
Finally, the Form of the application is converted to a RibbonForm by clicking the Ribbon smart tag item Convert To a RibbonForm.
For the application menu and quick access toolbar items, the sidebar and toolbars layout management, handling the contextual tabs and updating icons when changing the resolution, a file is created that implements the requested behavior as follows:
The MainWindow_AppMenu_FileInfo file:
This file manages information about the currently loaded document. It provides methods to update the window caption and the enable state of the Save button when the content of the TextControl is changed by resetting it, typing, deleting or formatting text, loading a document or saving it.
private void UpdateMainWindowCaption() {
this.Text = m_strActiveDocumentName + (m_bIsDirtyDocument ? "*" : "") + " - " + Properties.Resources.MainWindow_Caption_Product;
this.Refresh();
}
private void UpdateSaveEnabledState() {
m_rbtnSave.Enabled = m_bIsDirtyDocument && !m_bIsUnknownDocument;
}
Private Sub UpdateMainWindowCaption()
Text = m_strActiveDocumentName & If(m_bIsDirtyDocument, "*", "") & " - " & My.Resources.MainWindow_Caption_Product
Refresh()
End Sub
Private Sub UpdateSaveEnabledState()
m_rbtnSave.Enabled = m_bIsDirtyDocument AndAlso Not m_bIsUnknownDocument
End Sub
The MainWindow_AppMenu_New file:
Resets the content of the TextControl when clicking the New button. The file also contains code to invoke a message box that informs the user to decide whether resetting the content should be canceled or the changed document should (or should not) be saved before creating a new document, if unsaved changes were made.
private void New_Click(object sender, EventArgs e) {
// Check whether the document is dirty. In this case, the user is suggested to save that document.
if (SaveDirtyDocumentOnNew()) {
// Create a new document.
m_txTextControl.ResetContents();
// A new document is created. Now:
UpdateCurrentDocumentInfo(); // Reset the current document information.
UpdateMainWindowCaption(); // Update the caption of the application's main window.
UpdateSaveEnabledState(); // Update the enabled state of the Save button.
}
}
Private Sub New_Click(ByVal sender As Object, ByVal e As EventArgs)
' Check whether the document is dirty. In this case, the user is suggested to save that document.
If SaveDirtyDocumentOnNew() Then
' Create a new document.
m_txTextControl.ResetContents()
' A new document is created. Now:
UpdateCurrentDocumentInfo() ' Reset the current document information.
UpdateMainWindowCaption() ' Update the caption of the application's main window.
UpdateSaveEnabledState() ' Update the enabled state of the Save button.
End If
End Sub
The MainWindow_AppMenu_Open file:
Provides a method to load a document into TextControl. It is used by the Open button and when clicking a recent file item. Similar to the New and Exit button, before loading the document, a method checks for unsaved changes in the current content to invoke a corresponding message box if necessary.
When loading it, information about the document is stored by using the corresponding UpdateCurrentDocumentInfo method. Some of these settings (CssSaveMode, CssFileName and UserPassword) are used again when saving the loaded document by using the Save button.
Furthermore, in case the document is password protected, a FilterException is thrown. This Exception is handled by the
HandlePasswordProtectedDocument method that invokes a dialog to set the password for the document.
internal void Open(string fileName = null, StreamType streamType = (StreamType)(-1)) {
// Check whether the document is dirty. In this case, the user is suggested to save that document.
if (SaveDirtyDocumentOnOpen()) {
// Create settings to determine some load parameters and get information about the document
// when it is opened.
LoadSettings lsLoadSettings = CreateLoadSettings();
try {
// Check whether a file to load is specified.
if (string.IsNullOrEmpty(fileName)) {
// If not, the TextControl Load dialog is opened. In that dialog all loadable file
// formats can be chosen that are provided by the TXTextControl.StreamType enumeration.
if (m_txTextControl.Load(StreamType.All, lsLoadSettings) == DialogResult.Cancel) {
return;
}
}
else {
// Determine the stream type if necessary
if (streamType == (StreamType)(-1)) {
streamType = GetStreamType(fileName);
}
// Open the file directly by using its path.
m_txTextControl.Load(fileName, streamType, lsLoadSettings);
}
} catch (Exception ex) {
// Set the password if the document is password protected.
if (!HandlePasswordProtectedDocument(ex, lsLoadSettings)) {
return;
}
}
// The document is loaded. Now:
UpdateCurrentDocumentInfo(lsLoadSettings); // Set information about the loaded document.
AddRecentFile(m_strActiveDocumentPath); // Add the document to the recent files list.
UpdateMainWindowCaption(); // Update the caption of the application's main window.
UpdateSaveEnabledState(); // Update the enabled state of the Save button.
}
}
private bool HandlePasswordProtectedDocument(Exception exception, LoadSettings loadSettings) {
// Check whether the thrown exception is an exception of type FilterException.
if (exception is FilterException) {
switch ((exception as FilterException).Reason) {
case FilterException.FilterError.InvalidPassword:
// Open the password dialog if the document is write protected.
PasswordDialog dlgPassword = new PasswordDialog(m_txTextControl, loadSettings);
return dlgPassword.ShowDialog(this) == DialogResult.OK;
}
}
throw exception;
}
private void UpdateCurrentDocumentInfo(LoadSettings loadSettings) {
m_strActiveDocumentPath = loadSettings.LoadedFile;
m_stActiveDocumentType = m_stLastLoadedType = loadSettings.LoadedStreamType;
m_strUserPasswordPDF = loadSettings.UserPassword;
m_strCssFileName = loadSettings.CssFileName;
m_svCssSaveMode = CssSaveMode.None;
m_bIsDirtyDocument = false;
m_bIsUnknownDocument = false;
m_strActiveDocumentName = Path.GetFileName(m_strActiveDocumentPath);
}
Friend Sub Open(ByVal Optional fileName As String = Nothing, ByVal Optional streamType As StreamType = -1)
' Check whether the document is dirty. In this case, the user is suggested to save that document.
If SaveDirtyDocumentOnOpen() Then
' Create settings to determine some load parameters and get information about the document
' when it is opened.
Dim lsLoadSettings As LoadSettings = CreateLoadSettings()
Try
' Check whether a file to load is specified.
If String.IsNullOrEmpty(fileName) Then
' If Not, the TextControl Load dialog Is opened. In that dialog all loadable file
' formats can be chosen that are provided by the TXTextControl.StreamType enumeration.
If m_txTextControl.Load(StreamType.All, lsLoadSettings) = DialogResult.Cancel Then
Return
End If
Else
' Determine the stream type if necessary
If streamType = CType(-1, StreamType) Then
streamType = GetStreamType(fileName)
End If
' Open the file directly by using its path.
m_txTextControl.Load(fileName, streamType, lsLoadSettings)
End If
Catch ex As Exception
' Set the password if the document is password protected.
If Not HandlePasswordProtectedDocument(ex, lsLoadSettings) Then
Return
End If
End Try
' The document is loaded. Now:
UpdateCurrentDocumentInfo(lsLoadSettings) ' Set information about the loaded document.
AddRecentFile(m_strActiveDocumentPath) ' Add the document to the recent files list.
UpdateMainWindowCaption() ' Update the caption of the application's main window.
UpdateSaveEnabledState() ' Update the enabled state of the Save button.
End If
End Sub
Private Function HandlePasswordProtectedDocument(ByVal exception As Exception, ByVal loadSettings As LoadSettings) As Boolean
' Check whether the thrown exception is an exception of type FilterException.
If TypeOf exception Is FilterException Then
Select Case TryCast(exception, FilterException).Reason
Case FilterException.FilterError.InvalidPassword
' Open the password dialog if the document is write protected.
Dim dlgPassword As PasswordDialog = New PasswordDialog(m_txTextControl, loadSettings)
Return dlgPassword.ShowDialog(Me) = DialogResult.OK
End Select
End If
Throw exception
End Function
Private Sub UpdateCurrentDocumentInfo(ByVal loadSettings As LoadSettings)
m_strActiveDocumentPath = loadSettings.LoadedFile
m_stLastLoadedType = loadSettings.LoadedStreamType
m_stActiveDocumentType = m_stLastLoadedType
m_strUserPasswordPDF = loadSettings.UserPassword
m_strCssFileName = loadSettings.CssFileName
m_svCssSaveMode = CssSaveMode.None
m_bIsDirtyDocument = False
m_bIsUnknownDocument = False
m_strActiveDocumentName = Path.GetFileName(m_strActiveDocumentPath)
End Sub
The MainWindow_AppMenu_Save file:
Contains the method to save a document. It is used by both the Save and Save As... buttons and the unsaved changes checking routines of the New, Open and Exit buttons.
When saving it, information about the document is stored by using the corresponding UpdateCurrentDocumentInfo method. Some of these settings (CssSaveMode, CssFileName and UserPassword) are used when saving the saved document again by using the Save button.
private bool Save(string savePath) {
// Create settings to determine some save parameters and get information about the document
// when it is saved.
SaveSettings svsSaveSettings = CreateSaveSettings();
// Check whether a file path is specified where the document should be loaded.
if (string.IsNullOrEmpty(savePath)) {
// If no such path is determined, the TextControl Save dialog is opened. In that dialog
// all file formats can be chosen that are provided by the TXTextControl.StreamType enumeration.
// Furthermore the DialogSettings EnterPassword, StylesheetOptions and SaveSelection are set.
if (m_txTextControl.Save(StreamType.All, svsSaveSettings,
SaveSettings.DialogSettings.EnterPassword |
SaveSettings.DialogSettings.StylesheetOptions |
SaveSettings.DialogSettings.SaveSelection) == DialogResult.Cancel) {
return false;
}
}
else {
// Save the document at the same location (and with the same format) where it was loaded
// before.
svsSaveSettings.CssSaveMode = m_svCssSaveMode; // Set the stored css save mode.
svsSaveSettings.CssFileName = m_strCssFileName; // Set the stored css file name.
svsSaveSettings.UserPassword = m_strUserPasswordPDF; // Set the stored user password.
m_txTextControl.Save(m_strActiveDocumentPath, m_stActiveDocumentType, svsSaveSettings);
}
// The document is saved. Now:
UpdateCurrentDocumentInfo(svsSaveSettings); // Set information about the saved document.
AddRecentFile(m_strActiveDocumentPath); // Add the document to the recent files list.
UpdateMainWindowCaption(); // Update the caption of the application's main window.
UpdateSaveEnabledState(); // Update the enabled state of the Save button.
return true;
}
private void UpdateCurrentDocumentInfo(SaveSettings saveSettings) {
m_strActiveDocumentPath = saveSettings.SavedFile;
m_stActiveDocumentType = m_stLastSavedType = saveSettings.SavedStreamType;
m_strUserPasswordPDF = saveSettings.UserPassword;
m_strCssFileName = saveSettings.CssFileName;
m_svCssSaveMode = saveSettings.CssSaveMode;
m_bIsDirtyDocument = false;
m_bIsUnknownDocument = false;
m_strActiveDocumentName = Path.GetFileName(m_strActiveDocumentPath);
}
Private Function Save(ByVal savePath As String) As Boolean
' Create settings to determine some save parameters and get information about the document
' when it is saved.
Dim svsSaveSettings As SaveSettings = CreateSaveSettings()
' Check whether a file path is specified where the document should be loaded.
If String.IsNullOrEmpty(savePath) Then
' If no such path Is determined, the TextControl Save dialog Is opened. In that dialog
' all file formats can be chosen that are provided by the TXTextControl.StreamType enumeration.
' Furthermore the DialogSettings EnterPassword, StylesheetOptions And SaveSelection are set.
If m_txTextControl.Save(StreamType.All, svsSaveSettings,
SaveSettings.DialogSettings.EnterPassword Or
SaveSettings.DialogSettings.StylesheetOptions Or
SaveSettings.DialogSettings.SaveSelection) = DialogResult.Cancel Then
Return False
End If
Else
' Save the document at the same location (and with the same format) where it was loaded
' before.
svsSaveSettings.CssSaveMode = m_svCssSaveMode ' Set the stored css save mode.
svsSaveSettings.CssFileName = m_strCssFileName ' Set the stored css file name.
svsSaveSettings.UserPassword = m_strUserPasswordPDF ' Set the stored user password.
m_txTextControl.Save(m_strActiveDocumentPath, m_stActiveDocumentType, svsSaveSettings)
End If
' The document is saved. Now:
UpdateCurrentDocumentInfo(svsSaveSettings) ' Set information about the saved document.
AddRecentFile(m_strActiveDocumentPath) ' Add the document to the recent files list.
UpdateMainWindowCaption() ' Update the caption of the application's main window.
UpdateSaveEnabledState() ' Update the enabled state of the Save button.
Return True
End Function
Private Sub UpdateCurrentDocumentInfo(ByVal saveSettings As SaveSettings)
m_strActiveDocumentPath = saveSettings.SavedFile
m_stLastSavedType = saveSettings.SavedStreamType
m_stActiveDocumentType = m_stLastSavedType
m_strUserPasswordPDF = saveSettings.UserPassword
m_strCssFileName = saveSettings.CssFileName
m_svCssSaveMode = saveSettings.CssSaveMode
m_bIsDirtyDocument = False
m_bIsUnknownDocument = False
m_strActiveDocumentName = Path.GetFileName(m_strActiveDocumentPath)
End Sub
The MainWindow_AppMenu_Print file:
Implements handlers to enforce quick printing, opening the print dialog and showing a print preview.
The MainWindow_AppMenu_DocumentSettings file:
Shows or hides the Document Settings sidebar.
The MainWindow_AppMenu_About file:
Toggles the About sidebar.
The MainWindow_AppMenu_Exit file:
Handles the closing of the application when the Exit or the Form's close button is clicked. Similar to the New and Open button, before closing the application, a method checks the document whether unsaved changes were made and invokes a corresponding message box if necessary.
The MainWindow_AppMenu_RecentFiles file:
Updates the recent files list when starting the application and loading or saving a document. The file paths of these documents are stored in a string collection that is saved as Settings property when closing the application. On opening the program, that collection is loaded into the recent files overview.
private void LoadRecentFiles() {
this.RecentFiles = Properties.Settings.Default.RecentFiles;
}
private void SaveRecentFiles() {
Properties.Settings.Default.RecentFiles = this.RecentFiles;
Properties.Settings.Default.Save();
}
internal StringCollection RecentFiles {
get { return m_colRecentFiles; }
set
{
m_colRecentFiles = value ?? new StringCollection();
// Remove empty entries.
for (int i = m_colRecentFiles.Count - 1; i >= 0; i--) {
if (string.IsNullOrEmpty(m_colRecentFiles[i])) {
m_colRecentFiles.RemoveAt(i);
}
}
UpdateRecentFileList();
}
}
Private Sub LoadRecentFiles()
RecentFiles = My.Settings.Default.RecentFiles
End Sub
Private Sub SaveRecentFiles()
My.Settings.Default.RecentFiles = RecentFiles
Call My.Settings.Default.Save()
End Sub
Friend Property RecentFiles As StringCollection
Get
Return m_colRecentFiles
End Get
Set(ByVal value As StringCollection)
m_colRecentFiles = If(value, New StringCollection())
' Remove empty entries.
For i = m_colRecentFiles.Count - 1 To 0 Step -1
If String.IsNullOrEmpty(m_colRecentFiles(i)) Then
m_colRecentFiles.RemoveAt(i)
End If
Next
UpdateRecentFileList()
End Set
End Property
When loading or saving a document, the list is updated by inserting or moving the file to the top of the list.
private void AddRecentFile(string filePath) {
if (!string.IsNullOrEmpty(filePath)) {
// Check whether the list already contains that file.
if (m_colRecentFiles.Contains(filePath)) {
// In that case remove that file.
m_colRecentFiles.Remove(filePath);
}
else {
// Remove last entry if the current number of entries equals to the
// maximum number of recent files.
if (m_colRecentFiles.Count == m_iMaxRecentFiles) {
m_colRecentFiles.RemoveAt(m_iMaxRecentFiles - 1);
}
}
// Insert the file path at the top of the list.
m_colRecentFiles.Insert(0, filePath);
// Update the recent file items inside the ribbon's ApplicationMenuHelpPaneItems collection.
UpdateRecentFileList();
}
}
Private Sub AddRecentFile(ByVal filePath As String)
If Not String.IsNullOrEmpty(filePath) Then
' Check whether the list already contains that file.
If m_colRecentFiles.Contains(filePath) Then
' In that case remove that file.
m_colRecentFiles.Remove(filePath)
Else
' Remove last entry if the current number of entries equals to the
' maximum number of recent files.
If m_colRecentFiles.Count = m_iMaxRecentFiles Then
m_colRecentFiles.RemoveAt(m_iMaxRecentFiles - 1)
End If
End If
' Insert the file path at the top of the list.
m_colRecentFiles.Insert(0, filePath)
' Update the recent file items inside the ribbon's ApplicationMenuHelpPaneItems collection.
UpdateRecentFileList()
End If
End Sub
The MainWindow_QAT file:
Inserts references to buttons of the application menu into the quick access toolbar. Furthermore, an undo and a redo button is created and added with the corresponding behavior.
The MainWindow_Sidebars file:
Updates the layout of a sidebar when its content layout changed. By handling the PropertyChanged event of the System.ComponentModel.INotifyPropertyChanged interface, sidebar layout settings such as showing the title and pin button or determining the dialog style are set considering the current set content layout.
private void SidebarLeft_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) {
switch (e.PropertyName) {
case "ContentLayout":
switch (m_sbSidebarLeft.ContentLayout) {
case Sidebar.SidebarContentLayout.TrackedChanges:
m_sbSidebarLeft.ShowPinButton = true;
m_rtbtnDocumentSettings.Checked = false;
m_rtbtnAbout.Checked = false;
break;
case Sidebar.SidebarContentLayout.DocumentSettings:
m_sbSidebarLeft.ShowPinButton = false;
m_sbSidebarLeft.IsPinned = true;
m_rtbtnDocumentSettings.Checked = true;
m_rtbtnAbout.Checked = false;
break;
case Sidebar.SidebarContentLayout.About:
m_sbSidebarLeft.ShowPinButton = false;
m_sbSidebarLeft.IsPinned = true;
m_rtbtnDocumentSettings.Checked = false;
break;
}
break;
case "IsShown":
m_rtbtnDocumentSettings.Checked = m_sbSidebarLeft.ContentLayout == Sidebar.SidebarContentLayout.DocumentSettings && m_sbSidebarLeft.IsShown;
m_rtbtnAbout.Checked = m_sbSidebarLeft.ContentLayout == Sidebar.SidebarContentLayout.About && m_sbSidebarLeft.IsShown;
break;
}
}
Private Sub SidebarLeft_PropertyChanged(ByVal sender As Object, ByVal e As ComponentModel.PropertyChangedEventArgs)
Select Case e.PropertyName
Case "ContentLayout"
Select Case m_sbSidebarLeft.ContentLayout
Case Sidebar.SidebarContentLayout.TrackedChanges
m_sbSidebarLeft.ShowPinButton = True
m_rtbtnDocumentSettings.Checked = False
m_rtbtnAbout.Checked = False
Case Sidebar.SidebarContentLayout.DocumentSettings
m_sbSidebarLeft.ShowPinButton = False
m_sbSidebarLeft.IsPinned = True
m_rtbtnDocumentSettings.Checked = True
m_rtbtnAbout.Checked = False
Case Sidebar.SidebarContentLayout.About
m_sbSidebarLeft.ShowPinButton = False
m_sbSidebarLeft.IsPinned = True
m_rtbtnDocumentSettings.Checked = False
End Select
Case "IsShown"
m_rtbtnDocumentSettings.Checked = m_sbSidebarLeft.ContentLayout = Sidebar.SidebarContentLayout.DocumentSettings AndAlso m_sbSidebarLeft.IsShown
m_rtbtnAbout.Checked = m_sbSidebarLeft.ContentLayout = Sidebar.SidebarContentLayout.About AndAlso m_sbSidebarLeft.IsShown
End Select
End Sub
The MainWindow_Toolbars file:
Determines the display colors of the toolbars and sets the texts of the status bar.
The MainWindow_ContextualTabs file:
Shows and hides the contextual tabs. The Table Tools contextual tab with its Table Layout and Formulas tabs is shown when the TextControl input position is changed into a location inside a table.
private void TextControl_InputPositionChanged(object sender, EventArgs e) {
m_ctgTableTools.Visible = m_txTextControl.Tables.GetItem() != null;
}
Private Sub TextControl_InputPositionChanged(ByVal sender As Object, ByVal e As EventArgs)
m_ctgTableTools.Visible = m_txTextControl.Tables.GetItem() IsNot Nothing
End Sub
The Frame Tools contextual tab is shown when a frame is selected and hidden when it is deselected. If a chart frame is selected, both the Frame Formatting and the Chart Layout tabs are shown. If another frame base object is selected, only the Frame Formatting tab is shown.
private void TextControl_FrameSelected(object sender, FrameEventArgs e) {
// Check whether the selected frame is an object of type ChartFrame
if (e.Frame is ChartFrame) {
m_ctgFrameTools.Header = Properties.Resources.ContextualTabGroup_ChartTools; // Update group header
if (!m_ctgFrameTools.ContextualTabs.Contains(m_rtRibbonChartLayoutTab)) {
// Because Frame Tools group does not contain the chart layout tab, it is added.
m_ctgFrameTools.ContextualTabs.Add(m_rtRibbonChartLayoutTab);
}
}
// show the Frame Tools group
m_ctgFrameTools.Visible = true;
}
Private Sub TextControl_FrameSelected(ByVal sender As Object, ByVal e As FrameEventArgs)
' Check whether the selected frame is an object of type ChartFrame
If TypeOf e.Frame Is ChartFrame Then
m_ctgFrameTools.Header = My.Resources.ContextualTabGroup_ChartTools ' Update group header
If Not m_ctgFrameTools.ContextualTabs.Contains(m_rtRibbonChartLayoutTab) Then
' Because Frame Tools group does not contain the chart layout tab, it is added.
m_ctgFrameTools.ContextualTabs.Add(m_rtRibbonChartLayoutTab)
End If
End If
' show the Frame Tools group
m_ctgFrameTools.Visible = True
End Sub
The MainWindow_DpiChanged file:
Updates the icons of the custom buttons (e.g. those of the application menu) when the resolution changed.
The MainWindow file:
The MainWindow file connects inside the overridden OnLoad method the implemented behavior of the previous presented files with the application and sets the design of those elements that could not be determined by the designer.
Furthermore the TextControl mini toolbar is activated by setting the ShowMiniToolbar property to MiniToolbarButton.LeftButton | MiniToolbarButton.RightButton.