TX Words: The Ribbon Sample

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 and the contextual tabs management.

The source code for this example is contained in the following directories:

  • %USERPROFILE%\Documents\TX Text Control 32.0.NET for WPF\CSharp\TX Words\Ribbon
  • %USERPROFILE%\Documents\TX Text Control 32.0.NET for WPF\VB.NET\TX Words\Ribbon

Creating the Sample

After creating this WPF App (.Net Framework) sample project by using Visual Studio, first two modifications were applied to the MainWindow.xaml: Replacing the <Grid> element with <DockPanel> and using the RibbonWindow class instead Window for this application.

While replacing the <Grid> element with <DockPanel> can easily be realized by changing the corresponding XAML code line, changing the application context from Window to RibbonWindow needs more preparation:

First a reference to the System.Windows.Controls.Ribbon assembly must be added to the project. This can automatically be done by dragging and dropping a Ribbon control from the toolbox into the DockPanel. If no such Ribbon control already exists inside the toolbox, add it as follows:

Click Choose Toolbox Items... from the Tools main menu to customize the toolbox. In the tab WPF Components, filter for Ribbon and find the Ribbon from the assembly System.Windows.Controls.Ribbon. Select the control and confirm with OK.

Now, to use a RibbonWindow instead a Window apply the following changes:

1. Replace in MainWindow.xaml

<Window

with

<RibbonWindow

2. Replace in MainWindow.xaml.cs/MainWindow.xaml.vb

public partial class MainWindow : Window {
Partial Public Class MainWindow
        Inherits Window

with

public partial class MainWindow : RibbonWindow {
Partial Public Class MainWindow
        Inherits RibbonWindow

In the next step, below the <Ribbon> tag, a status bar, followed by three Sidebar controls and two ruler bars were dragged and dropped into the DockPanel. The status bar is docked to the bottom, the first ruler bar to the top and the second one to the left.

The first sidebar is docked to the bottom of the window by setting the DockPanel.Dock and the VerticalAlignment properties to Bottom. The other two sidebars are horizontally aligned by setting the DockPanel.Dock and the HorizontalAlignment properties to Right respectively Left.

To show the About sidebar on starting the application, the ContentLayout property is set to About. To prevent an unpinning of the sidebar, the smart tag's ShowPinButton property is set to False. The DialogStyle is set to StandardSizable.

Both other sidebars are hidden when running the sample. This was implemented by setting the IsShown property to False.

<WPF:StatusBar x:Name="m_sbStatusBar" ShowZoom="False" BorderStyle="VerticalColorScheme" DockPanel.Dock="Bottom"/>

<WPF:Sidebar x:Name="m_sbSidebarBottom" IsShown="False" VerticalAlignment="Bottom" DockPanel.Dock="Bottom"/>
<WPF:Sidebar x:Name="m_sbSidebarRight" IsShown="False" HorizontalAlignment="Right" DockPanel.Dock="Right"/>
<WPF:Sidebar x:Name="m_sbSidebarLeft" ContentLayout="About" HorizontalAlignment="Left" DockPanel.Dock="Left" ShowPinButton="False" DialogStyle="StandardSizable"/>

<WPF:RulerBar x:Name="m_rbHorizontalRulerBar" DockPanel.Dock="Top"/>
<WPF:RulerBar x:Name="m_rbVerticalRulerBar" HorizontalAlignment="Left" VerticalAlignment="Stretch" DockPanel.Dock="Left"/>

The predefined TX Text Control ribbon tabs RibbonFormattingTab, RibbonInsertTab, RibbonPageLayoutTab, RibbonViewTab, RibbonReferencesTab, RibbonProofingTab, RibbonPermissionsTab, RibbonFormFieldsTab and RibbonReportingTab were dragged and dropped from the tool box into the previously created <Ribbon> tag.

Additionally, all sidebars were connected to these tabs to show a specific layout and perform the corresponding behavior when the related button is clicked. For this sample, the predefined ribbon tabs are associated with the sidebars as follows:

<WPF:RibbonFormattingTab Name="m_rtRibbonFormattingTab"
     GotoHorizontalSidebar="m_sbSidebarBottom"
     StylesSidebar="m_sbSidebarRight"
     FindHorizontalSidebar="m_sbSidebarBottom"
     FindSidebar="m_sbSidebarRight"
     ReplaceHorizontalSidebar="m_sbSidebarBottom"
     ReplaceSidebar="m_sbSidebarRight"/>
<WPF:RibbonInsertTab Name="m_rtRibbonInsertTab" />
<WPF:RibbonPageLayoutTab Name="m_rtRibbonPageLayoutTab" />
<WPF:RibbonViewTab Name="m_rtRibbonViewTab"/>
<WPF:RibbonReferencesTab Name="m_rtRibbonReferencesTab"/>
<WPF:RibbonProofingTab Name="m_rtRibbonProofingTab"
     CommentsHorizontalSidebar="m_sbSidebarBottom"
     CommentsSidebar="m_sbSidebarRight"
     TrackedChangesHorizontalSidebar="m_sbSidebarBottom"
     TrackedChangesSidebar="m_sbSidebarLeft"/>
<WPF:RibbonPermissionsTab Name="m_rtRibbonPermissionsTab" />
<WPF:RibbonFormFieldsTab  Name="m_rtRibbonFormFieldsTab"
     ConditionalInstructionsSidebar="m_sbSidebarRight"/>
<WPF:RibbonReportingTab Name="m_rtRibbonReportingTab"
     FieldNavigatorSidebar="m_sbSidebarRight"/>

To implement a contextual tabs behavior when entering a table or selecting a frame the predefined ribbon tabs RibbonTableLayoutTab, RibbonFormulaTab (to format a table) and RibbonFrameLayoutTab (to format a frame base element) were added to the <Ribbon> tag. These tabs are allocated to a contextual tab group where the corresponding Header property value matches with the tab's ContextualTabGroupHeader property value.

<WPF:RibbonTableLayoutTab
    Name="m_rtRibbonTableLayoutTab" ContextualTabGroupHeader="{x:Static prop:Resources.ContextualTabGroup_TableTools}"/>
<WPF:RibbonFormulaTab
    Name="m_rtRibbonFormulaTab" ContextualTabGroupHeader="{x:Static prop:Resources.ContextualTabGroup_TableTools}"/>
<WPF:RibbonFrameLayoutTab
    Name="m_rtRibbonFrameLayoutTab" ContextualTabGroupHeader="{x:Static prop:Resources.ContextualTabGroup_FrameTools}"/>

<Ribbon.ContextualTabGroups>
    <RibbonContextualTabGroup
        Header="{x:Static prop:Resources.ContextualTabGroup_TableTools}"
            Name="m_ctgTableTools"
            Background="#6600FF00"/>
    <RibbonContextualTabGroup
        Header="{x:Static prop:Resources.ContextualTabGroup_FrameTools}"
            Name="m_ctgFrameTools"
            Background="#66FF00FF"/>
</Ribbon.ContextualTabGroups>

The items of the ribbon's application menu and the buttons of the quick access toolbar were created by adding the corresponding RibbonApplicationMenuItem elements to the Ribbon.ApplicationMenu respectively the RibbonButton controls to the Ribbon.QuickAccesToolBar.

Finally, a TextControl was dragged and dropped into the DockPanel. It is connected to the predefined ribbon tabs and toolbars by setting the corresponding TextControl property with the name of the desired control.

Additionally, a TextControl.Loaded event handler is added to set the focus to the TextControl when the application is started, the HideSelection property is set to False and the illustration of the TextControl is modified by specifying the desktop and shadow color.

<WPF:TextControl DockPanel.Dock="Top" x:Name="m_txTextControl" HideSelection="False"
    RibbonFormattingTab="m_rtRibbonFormattingTab"
    RibbonInsertTab="m_rtRibbonInsertTab"
    RibbonPageLayoutTab="m_rtRibbonPageLayoutTab"
    RibbonViewTab="m_rtRibbonViewTab"
    RibbonReferencesTab="m_rtRibbonReferencesTab"
    RibbonProofingTab="m_rtRibbonProofingTab"
    RibbonPermissionsTab="m_rtRibbonPermissionsTab"
    RibbonFormFieldsTab="m_rtRibbonFormFieldsTab"
    RibbonReportingTab="m_rtRibbonReportingTab"

    RibbonTableLayoutTab="m_rtRibbonTableLayoutTab"
    RibbonFormulaTab="m_rtRibbonFormulaTab"
    RibbonFrameLayoutTab="m_rtRibbonFrameLayoutTab"

    RulerBar="m_rbHorizontalRulerBar"
    VerticalRulerBar="m_rbVerticalRulerBar"
    StatusBar="m_sbStatusBar"

    Loaded="TextControl_Loaded_MainWindow">
    <WPF:TextControl.DisplayColors>
        <WPF:TextControlColors DesktopColor="#F5F6F7" DarkShadowColor="#F5F6F7" LightShadowColor="#F5F6F7" />
    </WPF:TextControl.DisplayColors>
</WPF:TextControl>

The Code Behind

For the application menu and quick access toolbar items, the sidebar and toolbars layout management and handling the contextual tabs, 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.Title = m_strActiveDocumentName + (m_bIsDirtyDocument ? "*" : "") + " - " + Properties.Resources.MainWindow_Caption_Product;
}

private void UpdateSaveEnabledState() {
        m_rbtnSaveQAT.IsEnabled =
        m_rmiSave.IsEnabled = m_bIsDirtyDocument && !m_bIsUnknownDocument;
}
Private Sub UpdateMainWindowCaption()
        Title = m_strActiveDocumentName & If(m_bIsDirtyDocument, "*", "") & " - " & My.Resources.MainWindow_Caption_Product
End Sub

Private Sub UpdateSaveEnabledState()
        Me.m_rbtnSaveQAT.IsEnabled = CSharpImpl.Assign(Me.m_rmiSave.IsEnabled, 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, RoutedEventArgs 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 RoutedEventArgs)
        ' Check whether the document is dirty. In this case, the user is suggested to save that document.
        If SaveDirtyDocumentOnNew() Then
                ' Create a new document.
                Me.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();
                // Check whether a file to load is specified.
                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) == WPF.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);
                                dlgPassword.Owner = this;
                                bool? bResult = dlgPassword.ShowDialog();
                                return bResult.HasValue && bResult.Value;
                }
        }
        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 Me.m_txTextControl.Load(StreamType.All, lsLoadSettings) = WPF.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.
                                Me.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(Me.m_txTextControl, loadSettings)
                                dlgPassword.Owner = Me
                                Dim bResult As Boolean? = dlgPassword.ShowDialog()
                                Return bResult.HasValue AndAlso bResult.Value
                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) == WPF.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) = WPF.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.
                Me.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 and opening the print dialog.

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 Windows'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:

Manages the layout of the quick access toolbar buttons and handles their behavior.

The MainWindow_Sidebars file:

Updates the layout of a sidebar when its content layout changed. By using appropriate property value changed handlers that are connected to the corresponding DependencyPropertyDescriptor instances, 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_ContentLayoutChanged(object sender, EventArgs e) {
        switch (m_sbSidebarLeft.ContentLayout) {
                case Sidebar.SidebarContentLayout.TrackedChanges:
                        m_sbSidebarLeft.ShowPinButton = true;
                        m_rtbtnDocumentSettings.IsChecked = false;
                        m_rtbtnAbout.IsChecked = false;
                        break;
                case Sidebar.SidebarContentLayout.DocumentSettings:
                        m_sbSidebarLeft.ShowPinButton = false;
                        m_sbSidebarLeft.IsPinned = true;
                        m_rtbtnDocumentSettings.IsChecked = true;
                        m_rtbtnAbout.IsChecked = false;
                        break;
                case Sidebar.SidebarContentLayout.About:
                        m_sbSidebarLeft.ShowPinButton = false;
                        m_sbSidebarLeft.IsPinned = true;
                        m_rtbtnDocumentSettings.IsChecked = false;
                        break;
        }
}
Private Sub SidebarLeft_ContentLayoutChanged(ByVal sender As Object, ByVal e As EventArgs)
        Select Case Me.m_sbSidebarLeft.ContentLayout
                Case Sidebar.SidebarContentLayout.TrackedChanges
                        Me.m_sbSidebarLeft.ShowPinButton = True
                        Me.m_rtbtnDocumentSettings.IsChecked = False
                        Me.m_rtbtnAbout.IsChecked = False
                Case Sidebar.SidebarContentLayout.DocumentSettings
                        Me.m_sbSidebarLeft.ShowPinButton = False
                        Me.m_sbSidebarLeft.IsPinned = True
                        Me.m_rtbtnDocumentSettings.IsChecked = True
                        Me.m_rtbtnAbout.IsChecked = False
                Case Sidebar.SidebarContentLayout.About
                        Me.m_sbSidebarLeft.ShowPinButton = False
                        Me.m_sbSidebarLeft.IsPinned = True
                        Me.m_rtbtnDocumentSettings.IsChecked = False
        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.Visibility = m_txTextControl.Tables.GetItem() != null ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
}
Private Sub TextControl_InputPositionChanged(ByVal sender As Object, ByVal e As EventArgs)
        Me.m_ctgTableTools.Visibility = If(Me.m_txTextControl.Tables.GetItem() IsNot Nothing, Windows.Visibility.Visible, Windows.Visibility.Collapsed)
End Sub

The Frame Tools contextual tab is shown when a frame is selected and hidden when it is deselected.

private void TextControl_FrameSelected(object sender, FrameEventArgs e) {
        // Show the Frame Tools group
        m_ctgFrameTools.Visibility = System.Windows.Visibility.Visible;
}
Private Sub TextControl_FrameSelected(ByVal sender As Object, ByVal e As FrameEventArgs)
        ' Show the Frame Tools group
        Me.m_ctgFrameTools.Visibility = Windows.Visibility.Visible
End Sub

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.