See introduction for inportant information BEFORE downloading any files.

Introduction
IMPORTANT INFORMATION: This code and example this article describes is purely ALPHA stage code, and as such is significantly below commercial or otherwise quality standards. It is highly recommended this code is not used for projects of importance, 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 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.
IMPORTANT INFORMATION: To use this code you must agree to the licensing agreement and guidelines as set out by Microsoft. 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.
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;
using DNBSoft.WPF.RibbonControl;
Ribbon Control Linking Requirements (new style method, RECOMMENDED)
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 (new style method, 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.
Ribbon Control Linking Requirements (old style method, NOT RECOMMENDED)
This method is no longer recommended as the preceeding paragraph presents a significantly more simplistic method for implementing Ribbon controls, as well as the other required parts of the Office UI Guidelines.

Two objects must be created to link the ribbon onto; a Grid for the title bar (i.e. the bar used to select the ribbon, e.g. Home, Insert, Page Layout, etc. in Microsoft Office Word 2007 (hereafter Word), shown in green), and a Title for the actual ribbon bar itself (e.g. the bar containing Clipboard, Font, Paragraph, etc. for the 'Home' bar in Word, shown in red). In cases where only one ribbon is to be shown (note, ribbon refers to a User Interface (UI) element to be added to the ribbon bar), the title bar may be created but not linked to the UI should the developer wish the title bar not to be displayed (although the UI guidelines should be checked for validity). Note that in a future version an addition object will be required for linking the context sensitive ribbon titles.
The title bar and ribbon bar hooks should be added to a StackPanel (orientation vertical) in a Dock.Top position, to allow correct hiding of the Ribbon when the parent window's width is less than 300pixels. Setting the vertical alignment of the ribbon hook to top may improve UI behaviour in some circumstances, and generally is considered to be a 'good move' (not this may no longer apply in version 1.0.0.3, untested). Note the background colours and borders are not automatically set, but rather the titlebar should be linked, and the ribbon should be handled in the RibbonStyleHandler.StyleChanged event as below;
//in constructor
RibbonStyleHandler.StyleChanged += new RibbonStyleHandler.StyleChangedHandler(RibbonStyleHandler_StyleChanged);
RibbonStyleHandler_StyleChanged(null);
RibbonStyleHandler.styleRibbonTitleBackground(ribbonTitleBackground);
//in StyleChanged handler
ribbonBorder.Background = RibbonStyleHandler.RibbonBarBackground.Clone();
ribbonBorder.BorderBrush = new SolidColorBrush(RibbonStyleHandler.ButtonBorderNormal);
ribbonBorderWrapperGrid.Background = RibbonStyleHandler.RibbonTitleBackground.Clone();
Note however that this is liable to significant change in future versions as the linking will be created via a custom Window class.
Linking to Ribbon Control
Linking is performed via the main entry point into the ribbon control package, i.e. RibbonController;
RibbonController rc = new RibbonController(ribbonHook, titleHook);
In addition to linking the ribbon bar and title bar to the UI, the RibbonController class presents methods for adding and removing RibbonBar objects. The addRibbonBar(String title, RibbonBar bar) method accepts a title for the ribbon (as shown on the button to select the ribbon) and the ribbon itself.
RibbonBar b = new RibbonBar();
rc.addRibbonBar("Name", b);
RibbonBar
RibbonBar represents one ribbon within the control, and may contain any number (including none) of RibbonGroupBoxes. RibbonGroupBoxes may be added or removed via addRibbonGroupBox(RibbonGroupBox box) and removeRibbonGroupBox box respectively. Note that currently adding and removing RibbonGroupBoxes is currently performed via methods rather than properties which is subject to change in the next version. Furthermore RibbonGroupBoxes are added to the ribbon in the order they are added via addRibbonGroupBox(RibbonGroupBox box), and as such currently cannot be re-ordered except by removal and re-addition. See previous code example.
RibbonGroupBox

RibbonGroupBox groups UI elements with similar functionality together in a group, similar to that of WPF's GroupBox. The title of the group box may be set either via the constructor RibbonGroupBox(String text) or via the .Text property. In a similar way to that of RibbonBar, child elements are added via addRibbonComponent(UIElement element) and removeRibbonComponent(UIElement element). Unlike RibbonBar however, any UIElement may be added as a child, this is allowed to enable custom components to be more easily created and added (use existing controls such as RibbonButton to aid design).
Typically the following included elements may be added;
RibbonButton
RibbonDoubleButton
RibbonPreviewBoxes
RibbonThreeRowsLayout
RibbonTwoRowsLayout
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). Ultimately this control will be used when reducing the width of the ribbon when resizing the parent window smaller. The RibbonDoubleButton consists of three components, an image, descriptive text, and a context menu; an example of Word's paste button is shown below;
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);
RibbonDoubleButton rdb = new RibbonDoubleButton();
rdb.Image = new BitmapImage(new Uri(Environment.CurrentDirectory
+ @"\\Standard Icons\paste_from_clipboard.png", UriKind.RelativeOrAbsolute));
rdb.Text = "Paste";
rdb.SubMenu = contextMenu;
Note that ContextMenu 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. .Image receives an ImageSource object, preferably of a portable network graphics (PNG) type due to its inherent transparency support. *If sufficiently requested I will add a .Image property accepting a String of the filename / location.
RibbonPreviewBoxes


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. Currently there is neither highlighting for the current selection or an event handler for when the selection changes; these features will be available in the next release. RibbonPreviewBoxes may be added to the RibbonPreviewBoxes control via addRibbonPreviewBox(RibbonPreviewBox rpb) method, again adding the component at the end of the existing children. 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;
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 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;
Collapse
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

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;
Collapse
hbg = new RibbonHalfButtonGroup();
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);
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);
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.


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.

After key 'H' is pressed;

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;

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.
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.
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;
- Application starts with ribbon too minamised
- When resizing bigger
RibbonThridLabels flick smaller and bigger
- Resizing often jumpy and lag
- 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
RibbonThirdLayout, multiple children on same row overlap (fixed in next release)
RibbonThirdLayout, resize bigger on element with multiple children per row expands too early, width incorrectly reported
- Miscellaneous error with resizing
RibbonPreviewBoxes
- 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
RibbonPreviewBoxes popup (via right hand button) previews do not link events to .Previews properties