Version 1.0.0.10
Source Code and Compiled Binaries
See introduction for inportant information BEFORE downloading any files.
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;
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.
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;
RibbonBar
RibbonBar
represents one ribbon within the control, and may contain any number (including none) of RibbonGroupBox
es. RibbonGroupBox
es 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
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
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;
#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();
rdb.ControlID = new Guid("{CFEACF92-062B-4a59-822A-3F6F2B1C9210}");
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
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. RibbonPreviewBox
es 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;
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 RibbonThirdLabel
s 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
RibbonThirdLabel
s is shown below;
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 RibbonHalfButtonGroup
s, 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;
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);
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.
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.
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;
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 UIElement
s 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; RibbonTwoRowLayout
s 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.
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.