# Creating A Windows Forms Ribbon Application

> This tutorial walks through building a Windows Forms ribbon application with TX Text Control .NET for Windows Forms, covering ribbon tab configuration, contextual tab groups for table and frame layout tools, and adding Load and Save buttons to the ribbon Application Menu.

- **Author:** Bjoern Meyer
- **Published:** 2020-01-01
- **Modified:** 2026-03-05
- **Description:** This tutorial walks through building a Windows Forms ribbon application with TX Text Control .NET for Windows Forms, covering ribbon tab configuration, contextual tab groups for table and frame layout tools, and adding Load and Save buttons to the ribbon Application Menu.
- **7 min read** (1313 words)
- **Tags:**
  - Windows Forms
  - Tutorial
- **Web URL:** https://www.textcontrol.com/blog/2020/01/01/creating-a-windows-forms-ribbon-application/
- **LLMs URL:** https://www.textcontrol.com/blog/2020/01/01/creating-a-windows-forms-ribbon-application/llms.txt
- **LLMs-Full URL:** https://www.textcontrol.com/blog/2020/01/01/creating-a-windows-forms-ribbon-application/llms-full.txt

---

Creating the project and controls
---------------------------------

In this first step, an application is created and Text Control is connected with a ribbon bar and ribbon tabs.

1. Start Visual Studio .NET and create a new project. Select either Visual Basic or C# as a project type, and *Windows Forms Application* as a template.
    
    ![image](https://s1-www.textcontrol.com/assets/dist/blog/2020/01/01/h/assets/n_winforms_tutorial_2010_1.webp "image")
2. Find the *TX Text Control 29.0* toolbox tab that was created automatically by the TX Text Control setup program. All usable TX Text Control controls and components are listed in this tab.
    
    ![image](https://s1-www.textcontrol.com/assets/dist/blog/2020/01/01/h/assets/n_winforms_tutorial_2010_2.webp "image")
3. Click on the *TextControl* icon and draw it on a form.
    
    ![image](https://s1-www.textcontrol.com/assets/dist/blog/2020/01/01/h/assets/n_winforms_tutorial_2010_3.webp "image")
4. Click on the Smart Tag (little right-facing arrow) in the upper right corner of TextControl. In the **Wizards** group, click on *Add a Ribbon*, *Add a Status Bar*, *Add a Ruler* and *Add a Vertical Ruler*. Do not insert a *ButtonBar*. Finally, click on *Arrange Controls Automatically*. The controls are now connected and docked to fill the container:
    
    ![image](https://s1-www.textcontrol.com/assets/dist/blog/2020/01/01/h/assets/n_winforms_tutorial_ribbon_4.webp "image")
5. On the form, select the ribbon control by clicking the blue File tab title in order to click on the Smart Tag in the upper right corner of the ribbon control. Click on *Add a RibbonFormattingTab*, *Add a RibbonInsertTab*, *Add a RibbonPageLayoutTab*, *Add a RibbonViewTab*, *Add a RibbonProofingTab* and *Add a RibbonReportingTab*.
    
    ![image](https://s1-www.textcontrol.com/assets/dist/blog/2020/01/01/h/assets/n_winforms_tutorial_ribbon_5.webp "image")
6. Build and start the application to see first results.
    
    ![image](https://s1-www.textcontrol.com/assets/dist/blog/2020/01/01/h/assets/n_winforms_tutorial_ribbon_6.webp "image")

Adding Contextual Ribbon Tabs
-----------------------------

In this step, contextual ribbon tabs for table and frame layout tasks are added and connected.

1. On the form, select the ribbon control by clicking the blue File tab title in order to click on the Smart Tag in the upper right corner of the ribbon control. Click on Add a *Quick Access Toolbar* to convert the form to a *Windows.Forms.Ribbon.RibbonForm*.
2. Select again the ribbon control by clicking the blue *File* tab title and find the *ContextualTabGroups* property in the *Properties* window.
    
    ![image](https://s1-www.textcontrol.com/assets/dist/blog/2020/01/01/h/assets/n_winforms_tutorial_ribbon_context_1.webp "image")
3. Open the *ContextualTabGroup Collection Editor* by clicking on the ellipsis button in the (Collection) value column of the *ContextualTabGroups* property.
4. In the *Collection Editor*, click on *Add* to add a new *Windows.Forms.Ribbon.ContextualTabGroup*. Name this group *m\_grpTableTools*, set the *Header* property to *Table Tools* and pick a *BackColor*.
    
    ![image](https://s1-www.textcontrol.com/assets/dist/blog/2020/01/01/h/assets/n_winforms_tutorial_ribbon_context_2.webp "image")
5. Find the *ContextualTabs* property in the *m\_grpTableTools* properties and click on the ellipsis button in the (Collection) value column to open the *RibbonTab Collection Editor*.
    
    Open the *Add* drop-down button and click the *RibbonTableLayoutTab* item.
    
    ![image](https://s1-www.textcontrol.com/assets/dist/blog/2020/01/01/h/assets/n_winforms_tutorial_ribbon_context_3.webp "image")
    
    Close the dialog by clicking *OK*.
6. Repeat step 4 and name this new group *m\_grpFrameTools*, set the *Header* property to *Frame Tools* and pick another *BackColor*.
7. Find the *ContextualTabs* property and click on the ellipsis button in the (Collection) value column to open the *RibbonTab Collection Editor*. Like in step 5, open the *Add drop-down button* and click the *RibbonFrameLayoutTab* item and close the dialog by clicking *OK*.
8. In the *Solution Explorer*, select the form *Form1* and choose *Code* from the *View* main menu. Add the following code, so that the complete *Form1* class code looks like this:
    
    ```
    public partial class Form1 : TXTextControl.Windows.Forms.Ribbon.RibbonForm
    {
        public Form1()
        {
            InitializeComponent();
    
            textControl1.InputPositionChanged += TextControl1_InputPositionChanged;
            textControl1.FrameSelected += TextControl1_FrameSelected;
            textControl1.FrameDeselected += TextControl1_FrameDeselected;
            textControl1.DrawingActivated += TextControl1_DrawingActivated;
            textControl1.DrawingDeselected += TextControl1_DrawingDeselected;
        }
    
        private void TextControl1_DrawingDeselected(object sender,
            TXTextControl.DataVisualization.DrawingEventArgs e)
        {
            if ((textControl1.Frames.GetItem() == null) &&
                (textControl1.Drawings.GetActivatedItem() == null))
            {
                m_grpFrameTools.Visible = false;
            }
        }
    
        private void TextControl1_DrawingActivated(object sender, 
            TXTextControl.DataVisualization.DrawingEventArgs e)
        {
            m_grpFrameTools.Visible = true;
        }
    
        private void TextControl1_FrameDeselected(object sender, 
            TXTextControl.FrameEventArgs e)
        {
            if ((textControl1.Frames.GetItem() == null) &&
                (textControl1.Drawings.GetActivatedItem() == null))
            {
                m_grpFrameTools.Visible = false;
            }
        }
    
        private void TextControl1_FrameSelected(object sender, 
            TXTextControl.FrameEventArgs e)
        {
            m_grpFrameTools.Visible = true;
        }
    
        private void TextControl1_InputPositionChanged(object sender, EventArgs e)
        {
            m_grpTableTools.Visible = textControl1.Tables.GetItem() != null;
        }
    }
    ```
    
     ```
    Public Partial Class Form1
        Inherits TXTextControl.Windows.Forms.Ribbon.RibbonForm
        Public Sub New()
            InitializeComponent()
    
            AddHandler textControl1.InputPositionChanged, AddressOf TextControl1_InputPositionChanged
            AddHandler textControl1.FrameSelected, AddressOf TextControl1_FrameSelected
            AddHandler textControl1.FrameDeselected, AddressOf TextControl1_FrameDeselected
            AddHandler textControl1.DrawingActivated, AddressOf TextControl1_DrawingActivated
            AddHandler textControl1.DrawingDeselected, AddressOf TextControl1_DrawingDeselected
        End Sub
    
        Private Sub TextControl1_DrawingDeselected(sender As Object, e As TXTextControl.DataVisualization.DrawingEventArgs)
            If (textControl1.Frames.GetItem() Is Nothing) AndAlso (textControl1.Drawings.GetActivatedItem() Is Nothing) Then
                m_grpFrameTools.Visible = False
            End If
        End Sub
    
        Private Sub TextControl1_DrawingActivated(sender As Object, e As TXTextControl.DataVisualization.DrawingEventArgs)
            m_grpFrameTools.Visible = True
        End Sub
    
        Private Sub TextControl1_FrameDeselected(sender As Object, e As TXTextControl.FrameEventArgs)
            If (textControl1.Frames.GetItem() Is Nothing) AndAlso (textControl1.Drawings.GetActivatedItem() Is Nothing) Then
                m_grpFrameTools.Visible = False
            End If
        End Sub
    
        Private Sub TextControl1_FrameSelected(sender As Object, e As TXTextControl.FrameEventArgs)
            m_grpFrameTools.Visible = True
        End Sub
    
        Private Sub TextControl1_InputPositionChanged(sender As Object, e As EventArgs)
            m_grpTableTools.Visible = textControl1.Tables.GetItem() IsNot Nothing
        End Sub
    End Class
    ```
9. Build and start the application.
    
    Insert a table using the *Table* drop-down wizard in the *Insert* ribbon tab. Set the input position into the table to see the contextual *Table Tools* tab.
    
    ![image](https://s1-www.textcontrol.com/assets/dist/blog/2020/01/01/h/assets/n_winforms_tutorial_ribbon_context_4.webp "image")

Adding an Application Menu
--------------------------

1. In the *Solution Explorer*, select the form *Form1* and choose *Designer* from the *View* main menu.
2. Select the ribbon control and find the *ApplicationMenuItems* property in the *Properties* window.
    
    ![image](https://s1-www.textcontrol.com/assets/dist/blog/2020/01/01/h/assets/n_winforms_tutorial_ribbon_context_5.webp "image")
3. Open the *Control Collection Editor* by clicking on the ellipsis button in the (Collection) value column of the *ApplicationMenuItems* property.
4. In the *Control Collection Editor*, click on *Add* to add a new *Windows.Forms.Ribbon.RibbonButton*. Name this button *m\_rbtnLoad* and set the *Text* property to *Load...*. Add a second button with the name *m\_rbtnSave* and the *Text* *Save...*. Close the dialog by clicking *OK*.
5. In the *Solution Explorer*, select the form *Form1* and choose *Code* from the *View* main menu. Attach two more events to the *Form1* constructor code, so that the complete constructor code looks like this:
    
    ```
    public Form1()
    {
        InitializeComponent();
    
        textControl1.InputPositionChanged += TextControl1_InputPositionChanged;
        textControl1.FrameSelected += TextControl1_FrameSelected;
        textControl1.FrameDeselected += TextControl1_FrameDeselected;
        textControl1.DrawingActivated += TextControl1_DrawingActivated;
        textControl1.DrawingDeselected += TextControl1_DrawingDeselected;
    
        m_rbtnLoad.Click += M_rbtnLoad_Click;
        m_rbtnSave.Click += M_rbtnSave_Click;
    }
    ```
    
     ```
    Public Sub New()
        InitializeComponent()
    
        textControl1.InputPositionChanged += TextControl1_InputPositionChanged
        textControl1.FrameSelected += TextControl1_FrameSelected
        textControl1.FrameDeselected += TextControl1_FrameDeselected
        textControl1.DrawingActivated += TextControl1_DrawingActivated
        textControl1.DrawingDeselected += TextControl1_DrawingDeselected
    
        AddHandler m_rbtnLoad.Click, AddressOf M_rbtnLoad_Click
        AddHandler m_rbtnSave.Click, AddressOf M_rbtnSave_Click
    End Sub
    ```
6. Under the *Form* constructor code, add the following two new event handler methods:
    
    ```
    private void M_rbtnSave_Click(object sender, EventArgs e)
    {
        textControl1.Save();
    }
    
    private void M_rbtnLoad_Click(object sender, EventArgs e)
    {
        textControl1.Load();
    }
    ```
    
     ```
    Private Sub M_rbtnSave_Click(sender As Object, e As EventArgs)
        textControl1.Save()
    End Sub
    
    Private Sub M_rbtnLoad_Click(sender As Object, e As EventArgs)
        textControl1.Load()
    End Sub
    ```
7. Build and start the application.
    
    When clicking on the *File* application menu, the two menu items are visible to load and save documents.
    
    ![image](https://s1-www.textcontrol.com/assets/dist/blog/2020/01/01/h/assets/n_winforms_tutorial_ribbon_context_6.webp "image")

---

## About Bjoern Meyer

As CEO, Bjoern is the visionary behind our strategic direction and business development, bridging the gap between our customers and engineering teams. His deep passion for coding and web technologies drives the creation of innovative products. If you're at a tech conference, be sure to stop by our booth - you'll most likely meet Bjoern in person. With an advanced graduate degree (Dipl. Inf.) in Computer Science, specializing in AI, from the University of Bremen, Bjoern brings significant expertise to his role. In his spare time, Bjoern enjoys running, paragliding, mountain biking, and playing the piano.

- [LinkedIn](https://www.linkedin.com/in/bjoernmeyer/)
- [X](https://x.com/txbjoern)
- [GitHub](https://github.com/bjoerntx)

---

## Related Posts

- [Windows Forms Tutorial: Create Your First Windows Forms C# Application](https://www.textcontrol.com/blog/2024/08/26/windows-forms-tutorial-create-your-first-windows-forms-csharp-application/llms.txt)
- [Creating Your First Windows Forms Application with C#](https://www.textcontrol.com/blog/2020/01/01/creating-your-first-windows-forms-application-with-csharp/llms.txt)
- [Document Permissions and Password Encryption](https://www.textcontrol.com/blog/2019/07/05/document-permissions-and-password-encryption/llms.txt)
- [Windows Forms and WPF: End a List on Return when Line is Empty](https://www.textcontrol.com/blog/2016/08/26/windows-forms-and-wpf-end-a-list-on-return-when-line-is-empty/llms.txt)
- [Using IFormattedText Objects to Access Elements Across All TextParts in a Document](https://www.textcontrol.com/blog/2016/08/25/using-iformattedtext-objects-to-access-elements-across-all-textparts-in-a-document/llms.txt)
- [Windows Forms: Printing Multiple Pages Per Sheet](https://www.textcontrol.com/blog/2015/07/24/windows-forms-printing-multiple-pages-per-sheet/llms.txt)
- [Inserting Watermark Images to All Pages Dynamically](https://www.textcontrol.com/blog/2015/07/17/inserting-watermark-images-to-all-pages-dynamically/llms.txt)
- [Reporting: Sorting Merge Block Rows by Column Name](https://www.textcontrol.com/blog/2015/07/15/reporting-sorting-merge-block-rows-by-column-name/llms.txt)
- [MailMerge: Conditional INCLUDETEXT Fields](https://www.textcontrol.com/blog/2015/01/08/mailmerge-conditional-includetext-fields/llms.txt)
- [TXTextControl.Markdown.Core 34.1.0-beta: Work with Full Documents, Selection, and SubTextParts](https://www.textcontrol.com/blog/2026/04/14/txtextcontrol-markdown-core-34-1-0-beta-work-with-full-documents-selection-and-subtextparts/llms.txt)
- [TX Spell .NET 11.0 SP1 is Now Available: What's New in the Latest Version](https://www.textcontrol.com/blog/2026/04/08/tx-spell-net-11-0-sp1-is-now-available/llms.txt)
- [TX Text Control 34.0 SP2 is Now Available: What's New in the Latest Version](https://www.textcontrol.com/blog/2026/02/18/tx-text-control-34-0-sp2-is-now-available/llms.txt)
- [TX Text Control 34.0 SP1 is Now Available: What's New in the Latest Version](https://www.textcontrol.com/blog/2025/12/03/tx-text-control-34-0-sp1-is-now-available/llms.txt)
- [Introducing TX Text Control 34.0: Your Next Leap in Document Processing](https://www.textcontrol.com/blog/2025/11/10/introducing-tx-text-control-34-0-your-next-leap-in-document-processing/llms.txt)
- [Sneak Peek: TX Text Control 34.0 Coming November 2025](https://www.textcontrol.com/blog/2025/10/02/sneak-peek-tx-text-control-34-0-coming-november-2025/llms.txt)
- [TX Text Control 33.0 SP3 is Now Available: What's New in the Latest Version](https://www.textcontrol.com/blog/2025/08/14/tx-text-control-33-0-sp3-is-now-available/llms.txt)
- [TX Text Control 33.0 SP2 is Now Available: What's New in the Latest Version](https://www.textcontrol.com/blog/2025/06/18/tx-text-control-33-0-sp2-is-now-available/llms.txt)
- [Document Lifecycle Optimization: Leveraging TX Text Control's Internal Format](https://www.textcontrol.com/blog/2025/05/16/document-lifecycle-optimization-leveraging-tx-text-controls-internal-format/llms.txt)
- [Expert Implementation Services for Legacy System Modernization](https://www.textcontrol.com/blog/2025/05/07/expert-implementation-services-for-legacy-system-modernization/llms.txt)
- [Service Pack Releases: What's New in TX Text Control 33.0 SP1 and 32.0 SP5](https://www.textcontrol.com/blog/2025/05/07/service-pack-releases-whats-new-in-tx-text-control-33-0-sp1-and-32-0-sp5/llms.txt)
- [Top 5 Real-World Applications for TX Text Control Document Processing Libraries](https://www.textcontrol.com/blog/2025/04/01/top-5-real-world-applications-for-tx-text-control-document-processing-libraries/llms.txt)
- [DWX Developer Week Moves to Mannheim - And Text Control Is on Board!](https://www.textcontrol.com/blog/2025/03/19/dwx-developer-week-moves-to-mannheim-and-tx-text-control-is-on-board/llms.txt)
- [The Wait is Over: TX Text Control for Linux is Officially Here](https://www.textcontrol.com/blog/2025/03/12/the-wait-is-over-tx-text-control-for-linux-is-officially-here/llms.txt)
- [Splitting Tables at Bookmark Positions and Cloning Table Headers](https://www.textcontrol.com/blog/2025/02/13/splitting-tables-at-bookmark-positions-and-cloning-table-headers/llms.txt)
- [Full .NET 9 Support in Text Control .NET Components for ASP.NET Core, Windows Forms, and WPF](https://www.textcontrol.com/blog/2024/11/11/full-net-9-support-in-text-control-net-components-for-asp-net-core-windows-forms-and-wpf/llms.txt)
