Click here to Skip to main content
15,867,330 members
Articles / Desktop Programming / WPF
Article

WPF C# Ribbon Control Library

Rate me:
Please Sign up or sign in to vote.
4.91/5 (97 votes)
25 Jun 2008CPOL26 min read 1.1M   43.2K   439   177
A WPF / C# Library for implementing Office 2007 Style Ribbon Interfaces
Version 1.0.0.10 Source Code and Compiled Binaries

See introduction for inportant information BEFORE downloading any files.

Image 1

ribboncontrol11.jpg

ribboncontrol21.jpg

ribboncontrol18.jpg

Introduction

IMPORTANT INFORMATION: This code and example this article describes is now BETA stage code, and as such may be below commercial or otherwise quality standards. It is recommended this code is not used for projects of short deadline, and that code modifications are kept to a minimum to reduce later work when the included source and binaries are updated. Please only use this code for minor projects currently, and check back for soon to come updates. This code DOES WORK however does not have all functionality added yet, such as some event handlers and other 'expected' features. Feel free to contact myself via email or otherwise for bug reports and feature requests. Thank you.

This article presents a library for producing Microsoft Office 2007 style ribbon interfaces; while the included source and binaries are in BETA 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.

IMPORTANT INFORMATION: To use this code you must agree to the licensing agreement and guidelines as set out by Microsoft. While the Office UI Guidelines are not currently legally required as the library owner and creator I am enforcing compilence with the guidelines, YOU MUST CONFORM. Part of these guidlines includes the requirement that you MUST have other components which are currently NOT part of this library; I in no way imply or otherwise that this library is sufficient for quilification for the Microsoft Office UI license. Ensuring you have these other components is YOUR responsibility. By downloading the source code or by using the source code you have agreed to follow download and follow the Microsoft required guidelines.

Please note that many of the screen shots are rather old, I will endevour to update them at some stage however try the demo as that will give you the latest look and feel. Please note they will be updated for version 1.0.0.11 of the library.

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[1] 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)

"ScreenTips help bridge the gap between the user interface and the Help system. ScreenTips appear when the mouse pointer hovers over a control in the 2007 Microsoft Office UI. ScreenTips display the name of the control, the beyboard shortcut for the control, and a brief description of the control.

Some ScreenTips in the 2007 Microsoft Office UI also provide F1 support, which opens Microsoft Office Help and takes the user directly to the related Help topic for the control whose ScreenTip was displayed when the F1 button was pressed." --- Microsoft

Using the Code (manual method, recommended)

The ribbon control presented herein is currently implemented via code behind and cannot be created via WPF in XAML code; this will change in later versions. The code to create ribbon style controls however are relatively simple and should not present any real difficulties for a moderately competent C# programmer. If in doubt, look at the sample code below.

The following code samples assume RibbonControl.dll has been linked and each source file referencing the ribbon control includes the package via;

C#
using DNBSoft.WPF.RibbonControl;

Ribbon Control Linking Requirements (RECOMMENDED FOR OFFLINE USE)

As of version 1.0.0.5 of the library, RibbonWindow is introduced which inherits the standard Window class and greatly simplifies the linking process (in fact making it trivial as it is done automatically now). Rather than linking the various components of the Office UI to a new Window, the Office UI requirements are implemented within a Window which can then be customised to suit needs.

The Ribbon is accessable via the .RibbonController property, the Quick Access Toolbar via the .QuickAccessToolbar property, and the Application Button via the .ApplicationButton property; all three properties are referance properties and are read only. Adding content to the Window is performed via the .Content property as normal; note however only one child element may be added to the Window, further children overwrite existing children, however this behaviour may change so except future versions to throw exceptions.

See the useful resources section below for an example application (including the source code for the demo application, as requested).

Online Ribbon Control Linking Requirements (RECOMMENDED FOR ONLINE USE)

As of version 1.0.0.6 of the library RibbonPage is introduced which inherits the standard Page class, and like RibbonWindow allows simplified creation of Ribbon enabled applications. The library will require 'full trust' permissions however otherwise you will recieve a not trusted error when trying to run the application; I will be adding a code project article in the next few days on how to accomplish this near impossible task!

Please note the styling of the window WILL change in the next few versions due to Office UI licensing issues. An online demo is available at the following address, http://www.derek-bartram.co.uk/index.cfm?PageID=ribbonControlDemo. Demo code to follow shortly.

Linking to Ribbon Control

The RibbonController class presents methods for adding and removing RibbonBar objects, and forms the central point for the Ribbon Control library. The .Ribbons property accepts a RibbonBar object to add to the window (as shown on the button to select the ribbon) and the ribbon itself.

C#
RibbonBar b = new RibbonBar();
rc.Children.Add(b);

RibbonControlBase

The base class for ALL ribbon elements, implements IRibbonControl (and is recommended as the base class for all custom controls). Contains the following main properties;

  • .NormalImage - The image displayed on the control when it is not disabled
  • .DisabledImage - The image displayed on the control when it is disabled
  • .NormalTip - The screen tip displayed when the control is not disabled, see below
  • .DisabledTip - The screen tip displayed when the control is disabled
  • .SubMenu - Not applicable for many controls, however for those it is (e.g. RibbonDoubleButton and RibbonThirdLabel) is the context menu shown when the expand arrow is clicked and the control is not disabled
  • .IsDefaultQuickAccessButton - if true shows the control on the Quick Access Toolbar at application startup (also used during resetting the Quick Access Toolbar)
  • .IsDefaultQuickAccessMenuButton - if true shows on the Quick Access Toolbar configuration menu
  • .IsEnabled - disables or enables the control, can generate multiple events due to switching between normal/disabled image and tip
  • .IsSelected - selects or de-selects the control, the control is coloured differently when selected indicating its selection
  • .ControlID - a unique GUID used for Quick Access Toolbar persistance
  • .Text - The text label shown on the control; for multiline controls using the | character indicates the line break

The following figure shows a number of buttons in different states of .IsEnabled and .IsSelected; note that the ribbon tabs themselves are special cases of ribbon buttons;

ribboncontrol20.jpg

RibbonBar

RibbonBar represents one ribbon within the control, and may contain any number (including none) of RibbonGroupBoxes. RibbonGroupBoxes may be added or removed via .Children.Add(RibbonGroupBox box) and .Children.Remove(RibbonGroupBox<code> box) respectively. RibbonGroupBoxes may be added in any order via the Insert member of .Children as per any Microsoft component.

RibbonGroupBox

Empty RibbonGroupBox

RibbonGroupBox groups UI elements with similar functionality together in a group, similar to that of WPF's GroupBox. In a similar way to that of RibbonBar, child elements are added via .Children.Add(IRibbonFullControl element) and removeRibbonComponent(IRibbonFullControl element).

Typically the following included elements may be added;

  • RibbonButton
  • RibbonDoubleButton
  • RibbonPreviewBoxes
  • RibbonThreeRowsLayout
  • RibbonTwoRowsLayout
  • RibbonThreeButtonsGroupLayout

RibbonDoubleButton

RibbonButton and RibbonDoubleButton

RibbonDoubleButton provides a full height button split in half horizontally, with the top half acting as a normal button and with the lower half opening a sub-menu (i.e. context menu). The RibbonDoubleButton consists of three components, an image, descriptive text, and a context menu; an example of Word's paste button is shown below;

C#
#region make context menu
ContextMenu contextMenu = new ContextMenu();
MenuItem m1 = new MenuItem();
m1.Header = "_Paste";
MenuItem m2 = new MenuItem();
m2.Header = "Paste _Special";
MenuItem m3 = new MenuItem();
m3.Header = "Paste as _Hyperlink";
MenuItem m4 = new MenuItem();
m4.Header = "Recent Files";
contextMenu.Items.Add(m1);
contextMenu.Items.Add(m2);
contextMenu.Items.Add(m3);
#endregion

RibbonDoubleButton rdb = new RibbonDoubleButton();
//Set a unique identifier for Quick Access Toolbar persistance
rdb.ControlID = new Guid("{CFEACF92-062B-4a59-822A-3F6F2B1C9210}");
//Set images
rdb.NormalImage = new BitmapImage(new Uri(Environment.CurrentDirectory 
     + @"\\Standard Icons\paste_from_clipboard.png", UriKind.RelativeOrAbsolute));
rdb.DisabledImage = new BitmapImage(new Uri(Environment.CurrentDirectory 
     + @"\\Standard Icons\paste_from_clipboard_disabled.png", UriKind.RelativeOrAbsolute));
rdb.Text = "Paste";
rdb.IsDefaultQuickAccessButton = true;
rdb.IsDefaultQuickAccessMenuButton = true;
rdb.SubMenu = contextMenu;
rdb.KeyboardAccessCombination = new RibbonKeyboardAccessKeyCombination("V");

Note that sub menu is the standard System.Windows.Controls.ContextMenu and is not automatically styled by the ribbon control package. Supplying a value of null to the .SubMenu property results in the default context menu of a single entry of "No Sub Menu". Should the intention be not to include a sub menu then the RibbonButton should be used instead.

RibbonPreviewBoxes

RibbonPreviewBoxes

ribboncontrol16.jpg

RibbonPreviewBoxes allows implementations of features such as that of the 'Styles' group in Word, i.e. a box containing various images representing states and the selection of them. RibbonPreviewBoxes may be added to the RibbonPreviewBoxes control via .Previews property. RibbonPreviewBox contains three significant properties; .Text sets the label in the preview (e.g. NONE above), .Image sets the image source of the preview, and .Header sets the group header when in popuped mode. RibbonPreviewBoxes contains the .setSelected(RibbonPreviewBox) method which selects the input preview and fires it's click event (note the preview must already be a member of .Previews). When the number of children exceeds that of the viewable space the up, down, and popup buttons may be used (all functional). RibbonPreviewBoxes have two properties, .Text and .Image to set the content. An example RibbonPreviewBoxes is shown below;

C#
RibbonPreviewBoxes rpb = new RibbonPreviewBoxes();

RibbonPreviewBox prb = new RibbonPreviewBox();
prb.Image = new BitmapImage(new Uri(Environment.CurrentDirectory 
          + @"\\Standard Icons\help.png", UriKind.RelativeOrAbsolute));
prb.Text = "Help";
rpb.addRibbonPreviewBox(prb);
prb = new RibbonPreviewBox();
prb.Image = new BitmapImage(new Uri(Environment.CurrentDirectory 
          + @"\\Standard Icons\enter_registration_key.png", UriKind.RelativeOrAbsolute));
prb.Text = "Key";
rpb.addRibbonPreviewBox(prb);
prb = new RibbonPreviewBox();
prb.Image = new BitmapImage(new Uri(Environment.CurrentDirectory 
          + @"\\Standard Icons\preview.png", UriKind.RelativeOrAbsolute));
prb.Text = "Preview";
rpb.addRibbonPreviewBox(prb);
prb = new RibbonPreviewBox();
prb.Image = new BitmapImage(new Uri(Environment.CurrentDirectory 
          + @"\\Standard Icons\print.png", UriKind.RelativeOrAbsolute));
prb.Text = "Print";
rpb.addRibbonPreviewBox(prb);
prb = new RibbonPreviewBox();
prb.Image = new BitmapImage(new Uri(Environment.CurrentDirectory 
          + @"\\Standard Icons\redo.png", UriKind.RelativeOrAbsolute));
prb.Text = "Redo";
rpb.addRibbonPreviewBox(prb);

RibbonThreeRowsLayout

RibbonThreeRowsLayout

RibbonThreeRowsLayout provides a layout manager for providing three rows of components at the standard ribbon heights and spacing. Typically this control is populated with RibbonThirdLabels via the .addRibbonComponent(RibbonThreeRowsLayout.Position position, UIElement element) method, where position refers to the row in which the component is added. Note that any number of components may be added to each row, however all rows will assume the width of the widest row. From experience of use of this control, it is recommended that only one child per row is added.

RibbonThirdLabel is a complex label allowing for an image, text, and sub menu (in that order) to be added, via the .Image, .Text, and .SubMenu properties accordingly. Note that like RibbonDoubleButton.SubMenu, RibbonThirdLabel.SubMenu does not automatically style the sub menu to the ribbon, however unlike RibbonDoubleButton.SubMenu rather than a null value resulting in a default menu it removes the drop down graphic from the label. An example of a complete RibbonThreeRowsLayout and three differently structured RibbonThirdLabels is shown below;
C#
RibbonThreeRowsLayout trl = new RibbonThreeRowsLayout();

RibbonThirdLabel rtl = new RibbonThirdLabel();
rtl.Image = new BitmapImage(new Uri(Environment.CurrentDirectory 
          + @"\\Standard Icons\paste_from_clipboard.png", UriKind.RelativeOrAbsolute));
trl.addRibbonComponent(RibbonThreeRowsLayout.Position.top, rtl);

rtl = new RibbonThirdLabel();
rtl.Image = new BitmapImage(new Uri(Environment.CurrentDirectory 
          + @"\\Standard Icons\paste_from_clipboard.png", UriKind.RelativeOrAbsolute));
rtl.Text = "Try this";
trl.addRibbonComponent(RibbonThreeRowsLayout.Position.middle, rtl);

#region context menu label
rtl = new RibbonThirdLabel();
rtl.Image = new BitmapImage(new Uri(Environment.CurrentDirectory 
          + @"\\Standard Icons\paste_from_clipboard.png", UriKind.RelativeOrAbsolute));
rtl.Text = "Try this";

contextMenu = new ContextMenu();
m1 = new MenuItem();
m1.Header = "Option _1";
m2 = new MenuItem();
m2.Header = "Option _2";
m3 = new MenuItem();
m3.Header = "Option _3";
m4 = new MenuItem();
m4.Header = "Option _4";
contextMenu.Items.Add(m1);
contextMenu.Items.Add(m2);
contextMenu.Items.Add(m3);
contextMenu.Items.Add(m4);

rtl.DropDownMenu = contextMenu;
trl.addRibbonComponent(RibbonThreeRowsLayout.Position.bottom, rtl);

RibbonTwoRowsLayout

RibbonTwoRowsLayout

Like RibbonThreeRowsLayout this component provides a row based layout manager, except rather than providing three rows it provides two rows. Typically this control contains RibbonHalfButtonGroups, which as the name suggests is used to group like items together using a unified border (with rounded corners at the end). Two provided children types are available, RibbonHalfButton and the less functionally complete RibbonHalfComboBox. All children elements added to the RibbonHalfButtonGroup must implement IRibbonHalfControl providing methods allowing the control to correctly style the borders of the children. For ease of use it is recommended that all children of RibbonTwoRowsLayout are wrapped in RibbonHalfButtonGroup to allow correct border colouring, however a call to setFullBorder() will suffice in cases where this is not adhered too. An example of these controls usage are;

C#
hbg = new RibbonHalfButtonGroup();

//Half combo box
RibbonHalfComboBox hcb = new RibbonHalfComboBox();
ComboBox cb = new ComboBox();

ComboBoxItem cbi1 = new ComboBoxItem();
cbi1.Content = "Combo 1";
ComboBoxItem cbi2 = new ComboBoxItem();
cbi2.Content = "Combo 2";
ComboBoxItem cbi3 = new ComboBoxItem();
cbi3.Content = "Combo 3";
ComboBoxItem cbi4 = new ComboBoxItem();
cbi4.Content = "Combo 4";

cb.Items.Add(cbi1);
cb.Items.Add(cbi2);
cb.Items.Add(cbi3);
cb.Items.Add(cbi4);

hcb.setComboBox(cb);
hbg.addComponent(hcb);

//Half buttons
RibbonHalfButton hb1 = new RibbonHalfButton(new BitmapImage(new Uri(Environment.CurrentDirectory 
          + @"\\Standard Icons/enter_registration_key.png", UriKind.RelativeOrAbsolute)));
RibbonHalfButton hb2 = new RibbonHalfButton(new BitmapImage(new Uri(Environment.CurrentDirectory 
          + @"\\Standard Icons/help.png", UriKind.RelativeOrAbsolute)));
RibbonHalfButton hb3 = new RibbonHalfButton(new BitmapImage(new Uri(Environment.CurrentDirectory 
          + @"\\Standard Icons/preview.png", UriKind.RelativeOrAbsolute)));
hbg.addComponent(hb1);
hbg.addComponent(hb3);
hbg.addComponent(hb5);
                

RibbonTwoRowsLayout trl2 = new RibbonTwoRowsLayout();                
trl2.addRibbonComponent(RibbonTwoRowsLayout.Position.bottom, hbg);                

RibbonThreeButtonsGroupLayout

The layout allows insertion of three full height controls and scales them down when available space is reduced; typically this control is used only for RibbonButton and RibbonDoubleButton instances. The control resises down from 3 full height buttons to 3 full RibbonThirdLabels in a RibbonThreeRowsLayout to 3 RibbonThidLabels with image and context menu (if applicable) only, and visa versa.

ScreenTips

As of version 1.0.0.2 of the library the ribbon now supports ScreenTips; note however that this is an ongoing development process and that the currently implementation does NOT meet the required guidelines.

Screen tips are simple to use, add, and even create. Custom screen tips should implement IScreenTip which requires a number of layout properties to be added to the control. All ribbon components extend RibbonControlBase which includes a property Tip which is used for getting and setting the ScreenTip. A library of ScreenTips is now included in ScreenTips.dll. Two types of ScreenTip are currently available, TextOnlyTip (displaying a heading, content text, and a help link) and ImageAndTextTip (displaying an additional image); both are shown below, however the screenshots do not convey the annimation effects present in the controls.

ribboncontrol10.jpg

ribboncontrol9.jpg

Using the Code (graphical design, not recommded)

Since the introduction of this library function, I have written a user interface for automatically generating the code to layout and link the controls to form a full ribbon bar. This tool is now available in the following article ribbonbuilder.aspx, A Graphical WPF Ribbon Control Builder.

The tool is an addition to the existing ribbon libary project, it does not provide a ribbon control but rather uses the ribbon control library of this project to produce specific layouts via a 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.

See the other article for precise usage details and the application, however please note refer to this article for details on linking the RibbonController.

IMPORTANT NOTE: This tool is currently out of date and will NOT produce code compatible with the current version of the library, therefore the manual method is recommended.

Keyboard Access Commands

Keyboard access is a requirement of the Office UI Guidelines, and as such must be implemented to be granted a legal license. When the user presses ALT or F10 the interface displays popups indicating Ribbon and Quick Access Toolbar shortcuts. In the case of the Ribbon, after the initial keystroke only tips for the Ribbon selection buttons are shown, and after further key presses the Ribbon component's tips are shown, see below.

ribboncontrol14.jpg

After key 'H' is pressed;

ribboncontrol15.jpg

Keyboard Access tips hide after a valid combination is pressed (e.g. HX, Home > Cut), when ALT or F10 is pressed again, if the mouse is clicked in the application, or the application looses focus.

Tips are added via the .KeyboardAccessCombination property and either altering the KeyCombination property of the returned object, or by supplying a new RibbonKeyboardAccessKeyCombination object. A new instance of RibbonKeyboardAccessController must be created linking the Ribbon and Quick Access Toolbar to the parent Window. Note that for testing purposes various constructors of RibbonKeyboardAccessController exist, however to conform to the UI Guidelines both the Ribbon and Quick Access Toolbar must be linked.

Should an invalid keyboard combination be attempted the last key press is automatically removed for retry, therefore the key presses 'H' 'R' 'T' 'L' '8' 'V' '3' would match Home > RTL3 and not Home > Paste. All invalid key presses are indicated via a ding sound. When a valid key combination is entered, the corresponding Ribbon's (or otherwise) Click event is fired, and as such no further coding is required to support keyboard access.

Ribbon Styling

Ribbon styling is performed automatically via RibbonStyleHandler. An event StyleChanged is thrown when the style has been changed and applied via reStyle() or reStyle(Style style). Four default styles have been included and are shown below;

ribboncontrol13.jpg

The RibbonStyleHandler class contains a number of static methods (specifically the many overloads of styleButtonBorder(...) and styleGroupBorder(...) for creating default styling and annimation linked to the current color pallet.

Custom Ribbon Controls

In a word, don't. This code is in ALPHA stage and so will change lots before BETA and FINAL and so you may very well end up writing your component twice. The article and code are to show what is coming with this control and not provide an actual usable component. Should you choose to write a custom control anyway (please do email me a copy and I may add it to the package, and of course give you your due credit) then I suggest looking at the XAML for the nearest existing control, in particular set your control to the correct height. I spent considerable effort getting the component sizes correct (not to mention this is a requirement of the Office UI Guidelines). Styling of the control should ideally be done using the static values in RibbonStyleHandler, and if possible .styleButtonBorder(...) and .styleGroupBorder(...) which will automatically animate both the borders and background of Border objects. All ribbon controls now extend RibbonControlBase which will provide the basic functionality for the control and will provide all the necassery storage properties for the class; do not fiddle with the properties, even on controls where they appear to have no meaning or use as they are ALL required by the Microsoft guidelines AND other components such as the Quick Access Toolbar.

Other Features

Please see the useful resources section as many features are shown in other articles due to size constrains.

Window Title

The window title styles as per Microsoft Office Word, as shown below;

ribboncontrol22.jpg

Points of Interest

Why use this code? Annoyingly, because Microsoft in their infinite wisdom failed to create this control for .NET 3.5. Who knows in the future they may, but currently as of the moment they have not and there is no news of plans too. However, in their defence they have licensed the usage of the Ribbon UI element for general use, subject to certain requirements, which may be found here. Please note the statement "This is very important to note because if you do not implement all of the required guidelines in the document, you are not legally allowed to use the ribbon user interface design!" should not hold true until a patent is granted, however I am currently working towards meeting all the design criteria anyway.

Are there alternatives to this work? Yes, although mostly they cost big money, however are significantly more developed. A better guide for this question has been produced by Bil Simser entitled Ribbon UI Control Roundup for Developers. Interestingly in the comments below it has been shown that Microsoft have released an MFC library for the Ribbon Control!

The popup class is unsurprisingly useful for popups such as the preview box; an article is forthcoming on how that particular control was produced. Curiously extending Popup is not actually necessarily the best approach to producing a popup.

The interactions between WPF and code-behind is considerably more complex when trying to code WPF resources from C#; in particular creating animations for UIElements from code-behind is particularly difficult. An article is forthcoming also.

10 Points and code credits go to the person who figures out why the animations seam to lag so much, and in many cases not show at all. Answers on a postcard please.

Known Bugs

The following is a list of bugs I am currently aware of; please leave a comment if you see any others;

  • Popups from minimised RibbonGroupBox often close too early, e.g. when scrolling a RibbonPreviewBoxes
  • Popups from minimised RibbonGroupBox do not close when lost focus or another non-group button pressed
  • Invalid keyboard combinations pressed for keyboard access do not produce ding sound
  • Keyboard tips display outside Window when Window is not sufficiently wide
  • Keyboard tips do not function correctly after initial ALT or F10 press; first key press ignored, therefore <any key> <key 2> is treated as <key 2> only.
  • RibbonPreviewBoxes resizes to any size when preview 0 is not visible
  • RibbonPreviewBox border does not display correctly when .Selected = true

Future Work

The following tasks are still being undertaken or being started;

  • Optimise ribbon resizing
  • Re-implement addComponent / removeComponent type methods to properties, allowing better order placement of children
  • Microsoft ribbon requirement conformity
  • Alt keyboard shortcut popups
  • RibbonGroupBox label scalling
  • Code cleanup
  • Keyboard Access bug fixing
  • RibbonPage styling to meet Office UI Guideline standard, including removal of 'window' title and borders

History

1.0.0.0 - Initial build: most controls and basic layout implemented, some styling consistent with Microsoft Office Word 2007, some event handlers.
1.0.0.1 - Ribbon resizing; RibbonTwoRowLayouts compress to three rows, RibbonPreviewBoxes expands and contracts previews and compresses to a drop down button, RibbonGroupBox compresses to a single drop down button, and RibbonThridLabels hide text. Multiple size varients per RibbonGroupBox.*
1.0.0.1 - RibbonGroupBox label button added.*
1.0.0.1 - Styles system updated; RibbonButton and RibbonDoubleButton both auto-restyle correctly, styles system updated to allow removal of styling by RibbonStyleHandler, and a new style added (green).
1.0.0.1 - Ribbon auto hiding when window width less than 300 pixels.*
1.0.0.2 - Ribbon Designer added, for graphical design of ribbons.
1.0.0.2 - ScreenTip support.
1.0.0.2 - Massive restructuring of code; IRibbonComponent and IRibbonResizing replaced with RibbonControlBase<code>.
1.0.0.2 - Default context menus added, including functionality to generate events when a control is to be added to the quick access bar.
1.0.0.2 - Restyling of the ribbon control bar, drop down shadow* and rounded corners*.
1.0.0.3 - Joined ScreenTips and RibbonControl into same package, i.e. RibbonControl.
1.0.0.3 - Added Quick Access Toolbar (QAT) support*; including linking Ribbon components to the QAT.
1.0.0.3 - Changed the structuring of Ribbon components; components now inherit from RibbonControlBase.
1.0.0.4 - Keyboard access added*; supports Ribbon, Ribbon components, and Quick Access Toolbar.
1.0.0.5 - Added RibbonWindow to simplify linking process.
1.0.0.6 - Event handling in RibbonPreviewBox / Selected properties of RibbonPreviewBox.
1.0.0.6 - RibbonPreviewBoxes only expands to number of children + 1 (the blank indicates no more in control, helps user).
1.0.0.6 - RibbonWindow no longer has myserious black box in background.
1.0.0.6 - RibbonPreviewBoxes.addRibbonPreviewBox(RibbonPreviewBox rpb) removed in favour of .Children property.
1.0.0.6 - RibbonGroupBox bug fix: LabelButtonPressed event now fires.
1.0.0.6 - RibbonPreviewBoxes bug fix: Clone() no longer throws exceptions when .Text or .Image are null.
1.0.0.6 - Added RibbonFileLocations and .RibbonBasePath property; static member indicating the base folder location for the application (useful when using RibbonPage for setting the online address for resources).
1.0.0.6 - Added RibbonPage used for XBAP style applications.
1.0.0.7 - RibbonController bug fix: Fixed force resize bigger.
1.0.0.7 - Removed RibbonWindow AllowTransparency="True"<code>. WPF Frame tag now displays without requiring complex work arounds.
1.0.0.7 - Reduced transparency into application area so WPF Frame tag works correctly; increased performance (see window loaded event handler in RibbonWindow).
1.0.0.7 - Performance improvement: RibbonWindow window styling returned to OS from user code.
1.0.0.7 - Performance improvement: RibbonWindow uses OS code to handle resize events, not WPF Window Resizing library.
1.0.0.7 - Performance improvement: RibbonBar resize handlers modified.
1.0.0.7 - Added RibbonDisplayTextBox: used to display simple text.
1.0.0.7 - Added RibbonDisplayImage: used to display full height images.
1.0.0.7 - Reduced number of dependancies, reduced load time.
1.0.0.8 - RibbonBar.addGroupBox(RibbonGroupBox) and RibbonBar.removeGroupBox(RibbonGroupBox) changed to List<RibbonGroupBox> RibbonBar.Children.
1.0.0.8 - RibbonButton.Text modified to allow multiline text; use | to indicate line break.
1.0.0.8 - Added RibbonUserControl, a resizing full height element for adding custom content into.
1.0.0.8 - Added RibbonHalfLabel, a half height label element (must be added as a child to RibbonHalfButtonGroup).
1.0.0.8 - Added RibbonHalfTextBox, a half height text input box (must be added as a child to RibbonHalfButtonGroup); use TextBoxText for text input, also contains EndPadding property for use when at the end of RibbonHalfButtonGroup.
1.0.0.8 - Added RibbonHalfPasswordBox, similar to RibbonHalfTextBox except with text obsuring; contains Password property.
1.0.0.8 - Added RibbonThreeButtonsGroupLayout, add three fullsize buttons to the layout and when space is limited they display as RibbonThirdLabels, complete with linked event handlers and properties (Text and Image).
1.0.0.8 - Changed RibbonControlBase to prevent layout controls showing in Quick Access Toolbar and configuration dialog.
1.0.0.8 - Quick Access Toolbar buttons now show a default tooltip of .Text when no .ScreenTip (= null) is defined.
1.0.0.8 - RibbonControlBase bug fix: Clicked event now calls only on left mouse button.
1.0.0.8 - RibbonController bug fix; RibbonBar now resizes to maximum size when a new RibbonBar is selected.
1.0.0.8 - RibbonController bug fix; automatically scales content when parent window/page first created.
1.0.0.8 - RibbonController bug fix; automatically scales content when first RibbonBar added.
1.0.0.8 - RibbonBar bug fix; automatically scales content when content added or removed.
1.0.0.8 - RibbonBar bug fix; fixed bug that made resizing call multiple times to gain propper size.
1.0.0.9 - Replaced addRibbonComponent(RibbonControlBase) and removeRibbonComponent(RibbonControlBase) in RibbonGroupBox with .Children property.
1.0.0.9 - RibbonPreviewBoxes bug fix: Popup previews now fires click event when a preview box clicked (i.e. clicking an element in the popup previews now fires the same event as per clicking an entry in the non-popuped version).
1.0.0.9 - RibbonPreviewBoxes.setSelected(RibbonPreviewBox) method added; sets the input as the selected box (and updates the minimised version's image). Input must be in the collection or an exception is thrown.
1.0.0.9 - RibbonPreviewBoxes .ShowPopupGroups property added, when set to true the popup from the ribbon preview now shows in groups (as set by the RibbonPreviewBox.Header property, also added).
1.0.0.9 - Added Application Menu* (see useful referances for more information)
1.0.0.9 - Removed dependancy for ApplicationMenu.dll, added into DNBSoft.WPF.RibbonControl namespace.
1.0.0.9 - Code cleanup - no warnings.
1.0.0.10 - Fixed keyboard shortcuts for Quick Access Toolbar, combinations now 01 -> 99, rather than 1-9,10-99 (hence error distinguishing 1 and 1.......... 0).
1.0.0.10 - RibbonPreviewBoxes bug fix: auto closes popup when focus lost.
10.0.0.10 - RibbonSelectionButton bug fix: selection buttons now annimate correctly, including first ribbon button .
10.0.0.10 - RibbonController now supports minimising the ribbon bar.
10.0.0.10 - RibbonThreeButtonGroupLayout bug fix: now handles cases were some of the buttons are null .
10.0.0.10 - RibbonWindow update title look and feel as per office.
10.0.0.10 - Added RibbonContextController for context ribbon support.
10.0.0.10 - RibbonDoubleButton.Text property now supports | for multiline text.
10.0.0.10 - RibbonButton, RibbonDoubleButton, and RibbonThirdLabel font size changed to 11pt to increase readability of letters extending below the line (e.g. lowercase g and j).
10.0.0.10 - RibbonColorPopup added; used to create themed color selection.
10.0.0.10 - Modified all controls to use RibbonBorder rather than Border (required for selected and enabled support).
10.0.0.10 - Added .IsEnabled and .IsSelected properties to RibbonControlBase.
10.0.0.10 - RibbonControlBase now implements IRibbonControl; i.e. the basic requirements of a control.
10.0.0.10 - IRibbonFullControl indicates a full height control.
10.0.0.10 - Changed .Image property to .NormalImage and added .DisabledImage. ImageChanged event fires when control enabled or disabled provided that .DisabledImage is not null.
10.0.0.10 - Changed .Tip property to .NormalTip and added .DisabledTip. ScreenTipChanged event fires when control enabled or disabled provided that .DisabledTip is not null. If .DisabledTip is null then .NormalTip is shown instead and ScreenTipChanged event does not fire. Note that ScreenTipChanged event will not fire when setting .DisableTip and .IsEnabled is true, and visa versa.
10.0.0.10 - RibbonSelectionButton bug fix: hover / selected styling now works correctly (via added RibbonStyleHandler.styleTabBorder and .styleTabText), including when double clicked minimised.
10.0.0.10 - Modified RibbonWindow so that scrolling over the ribbon tabs moves selected tab (only when non-minimised).*
10.0.0.10 - Changed RibbonWindow/RibbonPage so that when ribbon tab widths are greater than window width, they reduce in size and show separators.
10.0.0.10 - RibbonThreeButtonsGroupLayout bug fix: does not show context menu resulting in buttons not correctly adding to Quick Access Toolbar.
10.0.0.10 - QuickAccessButton bug fix: now shows relevant tool tip from parent control.
10.0.0.10 - RibbonButton bug fix: clicking bottom half of control now fires click event.
10.0.0.10 - RibbonControlBase bug fix: clicking control while control is disabled no longer fires click event.
10.0.0.10 - Added persistance to QuickAccessToolbar via getCurrentButtonControlIDs() and loadButtons(List<Guid> ids, RibbonController controller). Requires .ControlID property to be set for all persistance setable ribbon controls (recommended for ALL controls).

* Required by Microsoft Office UI Guidelines.

Useful Referances

roundbutton.aspx, A Microsoft Office Style WPF Application Button.

WPF_Window_Resizing.aspx, WPF Window Resizing; required for producing a Window replacement ground up (and hence making non-client area access comparable in complexity to client area).

qat.aspx, A Microsoft Office 2007 Style WPF C# Quick Access Toolbar; required for producing Quick Access Toolbars.

ribbonbuilder.aspx, A Graphical WPF Ribbon Control Builder; a graphical tool for producing complex ribbon layouts.

ribbondemo.aspx, source code for the demonstration application (as above).

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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Rail Research UK
United Kingdom United Kingdom
I originally studied for a masters in engineering of software engineering at The University of Birmingham during 2000-2004, of which I received a 2:1. I continued at Birmingham University working with Civil Engineering and Rail Research UK where I am currently in my final year of a 3 year PhD project developing a Computational Intelligent Approach to Railway Intervention Planning. Although my work has a significant focus on railway engineering and associated practices much of my work is with data mining (on SQL Server 2008) and computational intelligence (CI) techniques. My key areas of expertise in CI are clustering algorithms (including Rival Penalised Competitive Learning) and evolutionary algorithms.

Outside of my formal work I enjoy testing the latest technologies such as .NET 3.5 and the many frameworks of which it comprises (mainly WPF). I have several projects on the go including a .NET and DirectX port of Quake 3 and many utility libraries. I also maintain an extensive website coded in Cold Fusion which is regularly updated; more information is available about me there.

Comments and Discussions

 
QuestionProblem with Control Height Pin
Christian Oertel26-Oct-08 8:25
Christian Oertel26-Oct-08 8:25 
AnswerRe: Problem with Control Height Pin
Derek Bartram26-Oct-08 8:37
Derek Bartram26-Oct-08 8:37 
AnswerRe: Problem with Control Height Pin
Christian Oertel26-Oct-08 9:03
Christian Oertel26-Oct-08 9:03 
GeneralRe: Problem with Control Height Pin
Derek Bartram26-Oct-08 23:10
Derek Bartram26-Oct-08 23:10 
GeneralCrash in RibbonControl Pin
Member 424920216-Oct-08 23:07
Member 424920216-Oct-08 23:07 
GeneralLicense Pin
LasseL10-Oct-08 23:47
LasseL10-Oct-08 23:47 
GeneralRe: License Pin
Derek Bartram10-Oct-08 23:50
Derek Bartram10-Oct-08 23:50 
Generalhelp me run the Demo Pin
vinycc18-Oct-08 15:13
vinycc18-Oct-08 15:13 
I'm rum the demo code and have the message error:

'DNBSoft.WPF.RibbonControl.QuickAccessToolbar' does not contain a definition for 'getCurrentButtonControlIDs' and no extension method 'getCurrentButtonControlIDs' accepting a first argument of type 'DNBSoft.WPF.RibbonControl.QuickAccessToolbar' could be found (are you missing a using directive or an assembly reference?) C:\Users\paulo\Desktop\ribbondemo_src\RibbonDemonstration\QATPersistanceButtons.xaml.cs 45 46 RibbonDemonstration

the using and the dll are included in project
GeneralRe: help me run the Demo Pin
Derek Bartram11-Oct-08 0:06
Derek Bartram11-Oct-08 0:06 
QuestionRibbon Written in XAML? Pin
ignisw1-Oct-08 23:24
ignisw1-Oct-08 23:24 
AnswerRe: Ribbon Written in XAML? Pin
Derek Bartram2-Oct-08 3:10
Derek Bartram2-Oct-08 3:10 
QuestionRe: Ribbon Written in XAML? Pin
ignisw2-Oct-08 5:22
ignisw2-Oct-08 5:22 
AnswerRe: Ribbon Written in XAML? Pin
Derek Bartram2-Oct-08 6:05
Derek Bartram2-Oct-08 6:05 
General... Pin
falooley30-Sep-08 13:45
falooley30-Sep-08 13:45 
GeneralAddComponent method for ribbonhalfbuttongroup is not available Pin
Member 424920230-Sep-08 0:12
Member 424920230-Sep-08 0:12 
GeneralRe: AddComponent method for ribbonhalfbuttongroup is not available Pin
Derek Bartram11-Oct-08 0:07
Derek Bartram11-Oct-08 0:07 
GeneralExcellent Pin
VCSKicks5-Sep-08 18:42
VCSKicks5-Sep-08 18:42 
GeneralRe: Excellent Pin
Derek Bartram12-Sep-08 2:42
Derek Bartram12-Sep-08 2:42 
QuestionI can not use NotifyIcon in your nice WPF ribbon application Pin
tounkara18-Aug-08 8:21
tounkara18-Aug-08 8:21 
AnswerRe: I can not use NotifyIcon in your nice WPF ribbon application Pin
tounkara19-Aug-08 8:51
tounkara19-Aug-08 8:51 
QuestionCan we get the source code for a project that uses this control Pin
asdfasd nads a25-Jun-08 19:55
asdfasd nads a25-Jun-08 19:55 
AnswerRe: Can we get the source code for a project that uses this control Pin
Derek Bartram26-Jun-08 1:05
Derek Bartram26-Jun-08 1:05 
Questionlinking the dll in an project or vs2005 demo project? Pin
mightyCoCo20-Jun-08 4:56
mightyCoCo20-Jun-08 4:56 
AnswerRe: linking the dll in an project or vs2005 demo project? Pin
Derek Bartram23-Jun-08 1:18
Derek Bartram23-Jun-08 1:18 
Generalbug Pin
bougs26-May-08 11:01
bougs26-May-08 11:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.