Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A Graphical WPF Ribbon Control Builder

0.00/5 (No votes)
22 Mar 2008 2  
An article presenting Ribbon Builder, a tool for creating ribbon controls

RibbonControl library Version 1.0.0.9 supported

Ribbon Designer

Introduction

This tool is an addition to the existing code project page WPF C# Ribbon Control Library, it does not provide a ribbon control but rather uses the ribbon control library of the other project to produce specific layouts via a user interface (UI). The software provides a shortcut way of producing full ribbon controls without the need for coding; note however that it does not produce event handler hooks as this is beyond the scope of the application, the application is solely for producing layout. The code produced is for the older style manual connection method which is no longer recommended; it will be updated in the next release.

Please note that due to the ribbon control library being in alpha and the strong ties between the editor (i.e. this articles software), the compatibility of this editor and future version of the library is unclear. I shall endeavour to keep this application updated where appropiate. The editor does NOT and will NOT support third party components. This application is the first version, therefore it may contain bugs making it incompatible with the library, please report the bugs! Furthermore some non-essential functionality is not currently implemented (e.g. remove child, move up, move down, save, load), however it is possible to create all supported layouts of ribbon and use the generated code; the missing functionality will be added in a later release.

Background

"The ribbon is a graphical user interface widget composed of a strip across the top of the window that exposes all functions the program can perform in a single place, with additional ribbons appearing based on the context of the data.

One of the main driving ideas behind using a ribbon is enhancing usability; by consolidating the program's functions and commands in an easily recognizable place, one need not look through multiple levels of hierarchical menus, toolbars or task panes before finding the right command.

Recently, the ribbon has been implemented in Microsoft Office 2007 where Microsoft refers to it as the Office Fluent Ribbon and replaces menus, toolbars and many task panes. Microsoft claims that this will consolidate all the related functionality in one place and hence improve usability.

The ribbon is a pane that contains controls (such as buttons and icons) that are organized into a set of tabs, each one containing a grouping of relevant commands. Each application has a different set of tabs which expose the functionality that application offers.

For example, while Excel has a tab for working with formulas, Word has a tab for creating envelopes and mailings. Within each tab, related commands are grouped together. The ribbon is designed to make the features of the application more discoverable and accessible with fewer mouse clicks as compared to the menu-based UI used for all versions of Office prior to Office 2007.

Some tabs, called contextual tabs, appear only when an object is selected. Contextual tabs expose functionality specific only to the object with focus. For example, selecting a picture brings up the picture tools contextual tabs, which present commands for working with the picture. Similarly, focusing on a table exposes table-related options in a specific tab. Contextual tabs remain hidden when the object it works on are not selected." --- Wikipedia Ribbon (computing).

The WPF C# Ribbon Control Library article presents a library for producing Microsoft Office 2007 style ribbon interfaces; while the included source and binaries are in ALPHA release, it should be possible to implement even the most complex of ribbon style interfaces (albeit with minor alterations). Currently the library does not support creation of ribbon controls via WPF XAML code, however requires the creation of the ribbon bar via C# code behind. This reliance on code-behind creation is partially address with this article and software which produces the layout via a graphical method.

Using the Application

On starting RibbonDesigner.exe you will be presented with the main application interface, which is laid out as below. Note that you will not see the ribbon bar as it will not have any controls added to it yet, however the base RibbonController is initialised and linked to the application.

Ribbon Designer Layout

Ribbon

The ribbon presents a view of the ribbon bar being created; it is fully functional as the code that will ultimately be used to produce an actual application is actually used to implement the preview. Updates to the design structure are automatically applied to the preview. Note however that items with drop down menus will not show their menus due to ContextMenus not being created by the designer; this is not a bug moreover that ContextMenu generation is outside the scope of the application specification. RibbonPreviewBoxes popups do however work correctly as expected. Furthermore when RibbonGroupBox is minimised to its smallest form, the resulting drop down button will also work.

Stack (Content Stack)

The stack allows the creation of child nodes, and hence creates the structure of the ribbon; children of the ribbon component are nested deeper within the tree structure of the node representing the component. Nodes can be minimised and expanded to allow simpler construction and focusing, however nodes which have children added to them will re-expand (if not so already) automatically when the new child is added.

The add child button adds an appropriate child to the currently selected element; in many cases only one type of control may be added to a control however in the cases where this is not true a selection dialog with the valid children types are shown (e.g. below). Clicking the add child button multiple times results in multiple children being added; any node which supports the addition of children may accept any number of children, i.e. no control only allows a single child.

Remove child is not currently implemented. Due to the upcoming changes within the underlying library class the move up and move down buttons are also not implemented.

Child Type Selection

Element Options

The element options displays the relevant options for the currently selected element in the stack (as above). Generally there are a number of options;

  • Name, aka .Text, some String name placed on the component
  • Variable Name, the variable name of the object in code
  • Set Image button, aka .Image, an image to place on the component; Portable Network Graphics (PNG) is highly recommended

Application Options

The style drop down button allows the selection of the standard ribbon colors, as defined in RibbonStyleHandler.

The generate code button opens a new window containing the source code required to reproduce the preview ribbon. Note that when using the code in your own applications that you must link RibbonController as per the article WPF C# Ribbon Control Library. It is very highly recommended that when using the code that the Dynamic Link Library (dll) from the designer be used (i.e. RibbonControl.dll to ensure compatibility of code, however the modifications to the code are generally non-complex therefore it is worth attempting to fix any compile errors when trying an updated library. Grateful thanks would be given to anybody who can supply a syntax highlighter for the generate source dialog. The code as generated for the above screen shots is as follows;

Source Code

RibbonController controller = new RibbonController(ribbonHook, 
                                                   titleHook, 
                                                   parentWindow);

RibbonBar homeRibbonBar = new RibbonBar();
homeRibbonBar.Text = Home;

RibbonBar insertRibbonBar = new RibbonBar();
insertRibbonBar.Text = Insert;

RibbonBar reviewRibbonBar = new RibbonBar();
reviewRibbonBar.Text = Review;

RibbonGroupBox clipboardGroupBox = new RibbonGroupBox();
clipboardGroupBox.Text = Clipboard;
clipboardGroupBox.ShowLabelButton = false;

RibbonGroupBox controlsGroupBox = new RibbonGroupBox();
controlsGroupBox.Text = Controls;
controlsGroupBox.ShowLabelButton = false;

RibbonDoubleButton pasteButton = new RibbonDoubleButton();
pasteButton.Text = Paste;
pasteButton.Image = new BitmapImage(new Uri(
     @"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
   + @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
   + @"/paste_from_clipboard.png", UriKind.RelativeOrAbsolute));

RibbonThreeRowsLayout ribbon3RowsLayout_1 = new RibbonThreeRowsLayout();

RibbonThirdLabel ribbonThirdLabel_1 = new RibbonThirdLabel();
ribbonThirdLabel_1.Text = Cut;
ribbonThirdLabel_1.Image = new BitmapImage(new Uri(
     @"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
   + @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
   + @"/cut.png", UriKind.RelativeOrAbsolute));

RibbonThirdLabel ribbonThirdLabel_2 = new RibbonThirdLabel();
ribbonThirdLabel_2.Text = Copy;
ribbonThirdLabel_2.Image = new BitmapImage(new Uri(
     @"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
   + @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
   + @"/copy.png", UriKind.RelativeOrAbsolute));
ribbonThirdLabel_2.SubMenu = new ContextMenu();

RibbonThirdLabel ribbonThirdLabel_3 = new RibbonThirdLabel();
ribbonThirdLabel_3.Text = Format Painter;
ribbonThirdLabel_3.Image = new BitmapImage(new Uri(
     @"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
   + @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
   + @"/preview.png", UriKind.RelativeOrAbsolute));

RibbonTwoRowsLayout ribbon2RowsLayout_1 = new RibbonTwoRowsLayout();

RibbonHalfButtonGroup ribbonHalfButtonGroup_1 = new RibbonHalfButtonGroup();

RibbonHalfButtonGroup ribbonHalfButtonGroup_2 = new RibbonHalfButtonGroup();

RibbonHalfButton ribbonHalfButton_1 = new RibbonHalfButton();
ribbonHalfButton_1.Image = new BitmapImage(new Uri(
     @"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
   + @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
   + @"/e-mail.png", UriKind.RelativeOrAbsolute));

RibbonHalfButton ribbonHalfButton_2 = new RibbonHalfButton();
ribbonHalfButton_2.Image = new BitmapImage(new Uri(
     @"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
   + @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
   + @"/go_to_program_s_website.png", UriKind.RelativeOrAbsolute));

RibbonHalfButton ribbonHalfButton_3 = new RibbonHalfButton();
ribbonHalfButton_3.Image = new BitmapImage(new Uri(
     @"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
   + @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
   + @"/save.png", UriKind.RelativeOrAbsolute));

RibbonHalfButton ribbonHalfButton_4 = new RibbonHalfButton();
ribbonHalfButton_4.Image = new BitmapImage(new Uri(
     @"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
   + @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
   + @"/save_as.png", UriKind.RelativeOrAbsolute));

RibbonHalfButton ribbonHalfButton_5 = new RibbonHalfButton();
ribbonHalfButton_5.Image = new BitmapImage(new Uri(
     @"file:///C:/Users/Administrator/Documents/Visual Studio 2008"
   + @"/Projects/CIRIP_V2/CIRIP_V2/bin/Release/Standard Icons"
   + @"/save_all.png", UriKind.RelativeOrAbsolute));

controller.addRibbonBar((RibbonBar) homeRibbonBar);
homeRibbonBar.addRibbonGroupBox((RibbonGroupBox) clipboardGroupBox);
clipboardGroupBox.addRibbonComponent((IRibbonResizing) pasteButton);

clipboardGroupBox.addRibbonComponent((IRibbonResizing) ribbon3RowsLayout_1);
ribbon3RowsLayout_1.addRibbonComponent(RibbonThreeRowsLayout.Position.top, 
                                 (IRibbonResizing) ribbonThirdLabel_1);

ribbon3RowsLayout_1.addRibbonComponent(RibbonThreeRowsLayout.Position.middle, 
                                 (IRibbonResizing) ribbonThirdLabel_2);

ribbon3RowsLayout_1.addRibbonComponent(RibbonThreeRowsLayout.Position.bottom, 
                                 (IRibbonResizing) ribbonThirdLabel_3);



homeRibbonBar.addRibbonGroupBox((RibbonGroupBox) controlsGroupBox);
controlsGroupBox.addRibbonComponent((IRibbonResizing) ribbon2RowsLayout_1);
ribbon2RowsLayout_1.addRibbonComponent(RibbonTwoRowsLayout.Position.top, 
                                 (IRibbonResizing) ribbonHalfButtonGroup_1);
ribbonHalfButtonGroup_1.addComponent((IRibbonHalfControl) ribbonHalfButton_1);

ribbonHalfButtonGroup_1.addComponent((IRibbonHalfControl) ribbonHalfButton_2);


ribbon2RowsLayout_1.addRibbonComponent(RibbonTwoRowsLayout.Position.bottom, 
                                 (IRibbonResizing) ribbonHalfButtonGroup_2);
ribbonHalfButtonGroup_2.addComponent((IRibbonHalfControl) ribbonHalfButton_3);

ribbonHalfButtonGroup_2.addComponent((IRibbonHalfControl) ribbonHalfButton_4);

ribbonHalfButtonGroup_2.addComponent((IRibbonHalfControl) ribbonHalfButton_5);





controller.addRibbonBar((RibbonBar) insertRibbonBar);

controller.addRibbonBar((RibbonBar) reviewRibbonBar);

Note that some lines have been modified to keep the width of the article down. The save and load buttons are currently not implemented.

Using the Code

Generally the code will not be required as the compiled application should work correctly for the current version of the ribbon library, however it is included for completeness.

Window1 is the main window for the application. The user controls in the source are the options panels shown when selecting elements of the stack, and are generated when the node is selected (and correspondingly destroyed as a new node is selected). The SelectionWindow is a generalised Window for selection of an item from a List>String<. ResultsSourceWindow is used to present the resulting source code; this would be a good area for development by a third part, someone add some syntax highlighting please.

Points of Interest

Note that the set image buttons open a Windows.Forms.OpenFileDialog; curiously no open dialog is present in Windows Presentation Foundation. This lack has been noted in a number of computing forums and has been rather appropriatly called "a glaring oversight".

Known Bugs

  • Ribbon / application hangs when resizing the application window once elements have been added to the ribbon control, reason unknown
  • Not all controls in RibbonControl library supported / existing support total untested (please report all bugs in the comments below)

History

Version 1.0.0.0 --- Initial build
Version 1.0.0.1 --- Support for Version 1.0.0.9 of the RibbonControl library

Additional Licensing Notes

Please feel free to use this in your work, however please be aware that a modified The Code Project Open License (CPOL) is in use; basically it is the same as the standard license except that this code must not be used for commercial or not-for-profit commercial use without prior authorisation. Please see license.txt or license.pdf in the included source and demo files.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here