Ribbon Feature Walkthrough
The WPF team is excited to debut the preview version of our new WPF Ribbon control starting on Monday, October 27, 2008!
Binaries and source code for the Ribbon can be downloaded at the Office UI Licensing
site.
Introduction to the Office Ribbon
The preview version of the WPF Ribbon includes many of the features which Independent Software Vendors (ISVs)
need to add a Ribbon control to their WPF applications. Ribbon is a command bar that organizes a program's
features into a series of tabs at the top of a window. The Ribbon UI was designed by Microsoft Office to
increase discoverability of features and functions, enable quicker learning of the program as a whole, and
make users feel more in control of their experience with the program. The Ribbon is designed to replace the
traditional menu bar and toolbars. The WPF Ribbon will include all of the basic Ribbon features and functionality,
including tabs, groups, controls (buttons, split buttons, galleries, etc.), title bar integration of the
application menu button and quick access toolbar, and resizing with dynamic layout.
The Ribbon is a fairly complex piece of UI which is difficult to build without a basic understanding
of the control and the intended function of each of its components. Ribbon was introduced as part of
the Office 2007 suite and can be found in applications such as Word, PowerPoint, Excel, and Outlook.
If you’re not familiar with the Office Ribbon, there is a great overview of the Ribbon and its components
available on MSDN at http://msdn.microsoft.com/en-us/library/cc872782.aspx.
Feature Walkthrough
Basic Ribbon Construction
The Ribbon is composed of a collection of tabs, each of which contains a collection of groups, and each
group contains a collection of controls. Controls used the Ribbon can include buttons, split buttons,
checkboxes, drop-down menus, combo boxes, text boxes, spinners, and galleries. Many of these controls are
available in the preview release of the Ribbon and can be used to build a basic Ribbon structure like so:
<r:RibbonTab Label="Banking">
<r:RibbonGroup>
<r:RibbonButton Command="me:AppCommands.Cut"/>
<r:RibbonButton Command="me:AppCommands.Copy"/>
<r:RibbonButton Command="me:AppCommands.Paste"/>
</r:RibbonGroup>
<r:RibbonGroup>
<r:RibbonButton Command="me:AppCommands.AddNew"/>
<r:RibbonButton Command="me:AppCommands.Clear" />
<r:RibbonButton Command="me:AppCommands.Delete"/>
</r:RibbonGroup>
<r:RibbonGroup>
<r:RibbonButton Command="me:AppCommands.DownloadStatements"/>
<r:RibbonButton Command="me:AppCommands.DownloadCreditCards"/>
<r:RibbonButton Command="me:AppCommands.Transfer"/>
</r:RibbonGroup>
</r:RibbonTab>
RibbonCommands
One very important aspect of the WPF Ribbon is the new RibbonCommand feature. Unlike most UI development which
is view-centric, the Ribbon is more view-model centric. Every piece of UI on the Ribbon has an intent, which
can generally be considered an action which has UI (such as a label and icon) associated with it. These actions
can be used in multiple places on the Ribbon (such as within a group or in the Quick Access Toolbar). The
RibbonCommand was designed to encapsulate this information in one place.
Just like menus and toolbars, the Ribbon is driven through RoutedCommands. RibbonCommand is a new subclass
of RoutedCommand which includes the usual command properties plus some additional properties to associate
UI with each command. Each RibbonCommand has several pieces of information which are used to automatically
generate UI for the Ribbon:
- LabelTitle – used to display a label on the item in the Ribbon
- LabelDescription – used to display descriptive information
- ToolTipTitle – used to display a title for the tooltip created for the command
- ToolTipDescription – used to display a second line of text on the tooltip
- ToolTipImageSource – used to display an image on the tooltip
- SmallImageSource – the image used when the item is rendered in small size
- LargeImageSource – the image used when the item is rendered in large size
- ToolTipFooterTitle – used to display a footer title for the tooltip created for the command
- ToolTipFooterDescription – used to display a second line of text on the footer tooltip
- ToolTipFooterImageSource – used to display an image on the footer tooltip
RibbonCommands should be associated with each control and group on the Ribbon, the ApplicationMenu,
the menu items in the ApplicationMenu, and the controls in the QuickAccessToolBar. The Ribbon uses the
information in the RibbonCommand to automatically generate UI for the control. For example, defining a
RibbonButton without a command will simply create a blank button control. Once a RibbonCommand is assigned
to the button, however, the Ribbon automatically creates a label, icon, and tooltip for that button using
the information stored in the RibbonCommand. Since every control on the Ribbon can be used in more than
one place (for example, on the Ribbon and in the Quick Access Toolbar) and will need a Command associated
with it, using RibbonCommands makes it convenient to define the command and the UI one time and in one
place and then reuse the command wherever it’s needed.
A complete RibbonTab with RibbonGroups and controls would look like this:
<r:Ribbon>
<r:Ribbon.Resources>
<r:RibbonCommand x:Key="SaveCommand"
CanExecute="SaveCommand_CanExecute"
Executed="SaveCommand_Executed"
LabelTitle="Save"
SmallImageSource="Images\SaveIconSmall.png"
LargeImageSource="Images\SaveIconLarge.png"
ToolTipTitle="Save"
ToolTipDescription="Save your work." />
<r:RibbonCommand x:Key="AnotherCommand"
...
</r:Ribbon.Resources>
<r:RibbonTab Label="Home">
<r:RibbonGroup Command="{StaticResource Group1Command}">
<r:RibbonButton Command="{StaticResource SaveCommand}"/>
<r:RibbonButton Command="{StaticResource NewCommand}"/>
<r:RibbonButton Command="{StaticResource OpenCommand}"/>
</r:RibbonGroup>
<r:RibbonGroup Command="{StaticResource Group2Command}">
<r:RibbonButton Command="{StaticResource ClearCommand}"/>
<r:RibbonButton Command="{StaticResource DeleteCommand}" />
<r:RibbonButton Command="{StaticResource UndoCommand}"/>
<r:RibbonButton Command="{StaticResource RedoCommand}"/>
</r:RibbonGroup>
</r:RibbonTab>
</r:Ribbon>
RibbonWindow
One notable feature of the Office 2007 Ribbon is its integration with the window’s title bar.
Features like the ApplicationMenu button, the Quick Access Toolbar, and contextual tabs lay
on top of the non-client area, like so:
This can be achieved with the WPF Ribbon by using the new root element RibbonWindow.
RibbonWindow implements the interop code which is needed to render the necessary Ribbon
components in the title bar area. It is not required that Ribbon is used within the RibbonWindow,
but if title bar integration is desired, it is the simplest way to achieve it.
Ribbon Layout & Resizing
One of the most notable features of the Office Ribbon is its dynamic layout which changes as the
window resizes to display as many controls as possible in the most optimal layout. The WPF Ribbon
provides a variety of customization points where application authors can choose to specify the
Ribbon’s resizing behavior.
By default, each group is laid out using the standard RibbonWrapPanel. RibbonWrapPanel includes a
collection of pre-defined layout templates that it uses to arrange the controls, depending on how
many controls are in the group and how large the group is. For example, by default a group with
controls will lay out four large controls in the largest template, one large and three medium
controls in the medium template, one large and three small controls in the smallest template, and
will be collapsed (and display the largest template in a popup) in its final template:
If the application author wishes to change the default layout behavior, this is possible through
the GroupSizeDefinitions property. The developer can define a collection of GroupSizeDefinitions,
each of which represents a layout for the group. Within each GroupSizeDefinition, a ControlSizeDefinition
must be specified for each control within the group. The set of layout templates in the image above
would be defined like so:
<r:RibbonGroup Name="MoveDetails">
<r:RibbonGroup.Command>
<r:RibbonCommand LabelTitle="Move Details"
SmallImageSource="{StaticResource TimeframeIconDark}"/>
</r:RibbonGroup.Command>
<r:RibbonGroup.GroupSizeDefinitions>
<r:RibbonGroupSizeDefinitionCollection>
<r:RibbonGroupSizeDefinition>
<r:RibbonControlSizeDefinition ImageSize="Large"
IsLabelVisible="True"/>
<r:RibbonControlSizeDefinition ImageSize="Large"
IsLabelVisible="True"/>
<r:RibbonControlSizeDefinition ImageSize="Large"
IsLabelVisible="True"/>
<r:RibbonControlSizeDefinition ImageSize="Large"
IsLabelVisible="True"/>
</r:RibbonGroupSizeDefinition>
<r:RibbonGroupSizeDefinition>
<r:RibbonControlSizeDefinition ImageSize="Large"
IsLabelVisible="True"/>
<r:RibbonControlSizeDefinition ImageSize="Small"
IsLabelVisible="True"/>
<r:RibbonControlSizeDefinition ImageSize="Small"
IsLabelVisible="True"/>
<r:RibbonControlSizeDefinition ImageSize="Small"
IsLabelVisible="True"/>
</r:RibbonGroupSizeDefinition>
<r:RibbonGroupSizeDefinition>
<r:RibbonControlSizeDefinition ImageSize="Large"
IsLabelVisible="True"/>
<r:RibbonControlSizeDefinition ImageSize="Small"
IsLabelVisible="False"/>
<r:RibbonControlSizeDefinition ImageSize="Small"
IsLabelVisible="False"/>
<r:RibbonControlSizeDefinition ImageSize="Small"
IsLabelVisible="False"/>
</r:RibbonGroupSizeDefinition>
<r:RibbonGroupSizeDefinition IsCollapsed="True"/>
</r:RibbonGroupSizeDefinitionCollection>
</r:RibbonGroup.GroupSizeDefinitions>
<r:RibbonToggleButton Command="{StaticResource TimeFrameCommand}" />
<r:RibbonToggleButton Command="{StaticResource LocalMoveCommand}" />
<r:RibbonToggleButton Command="{StaticResource ChildrenCommand}" />
<r:RibbonToggleButton Command="{StaticResource FirstTimeBuyerCommand}" />
</r:RibbonGroup>
Application authors can also replace the default RibbonWrapPanel with a custom layout panel to
achieve more complex dynamic layout behaviors.
The order in which the groups collapse to a new a layout template can also be customized.
By default, groups will collapsed cyclically from right to left. Developers can customize
this behavior using the GroupSizeReductionOrder property:
<r:RibbonTab Label="Search Criteria" GroupSizeReductionOrder="Home,Price,Home,Home,Price,Categories">
<r:RibbonGroup Name="Price">
...
</r:RibbonGroup>
<r:RibbonGroup Name="Categories">
...
</r:RibbonGroup>
<r:RibbonGroup Name="Home">
...
</r:RibbonGroup>
</r:RibbonTab>
RibbonApplicationMenu & RibbonQuickAccessToolBar
The WPF Ribbon preview includes the RibbonApplicationMenu and the RibbonQuickAccessToolBar.
The RibbonApplicationMenu should have a RibbonCommand assigned which defines the icon inside
the Application Menu button and the action that double-clicking the button invokes.
RibbonApplicationMenu takes RibbonApplicationMenuItems and RibbonApplicationSplitMenuItems
as children. Like other controls, these menu items should have RibbonCommands associated with them.
The UI of the menu items will configure itself automatically using the information in the RibbonCommand
and depending on whether or not the menu item has children. If the item does have children,
an arrow will appear and mousing over the item will pop up a second menu displaying the children.
The RibbonQuickAccessToolBar takes a collection of Ribbon controls such as buttons, toggle buttons,
drop-down menus, etc. The Quick Access Toolbar (QAT) includes a Customize Menu which end-users can
use to add and remove controls from the QAT. Application authors can set the location of the QAT
controls using the attached property RibbonQuickAccessToolBar.Placement, which takes values of
InToolbar (not present in Customize Menu), InCustomizeMenu (in Customize Menu and unchecked), or
InCustomizeMenuAndToolbar (in Customize Menu and checked, therefore also present on Toolbar).
<r:Ribbon.QuickAccessToolBar>
<r:RibbonQuickAccessToolBar>
<r:RibbonButton Command="{StaticResource Phone1Command}"
r:RibbonQuickAccessToolBar.Placement="InCustomizeMenuAndToolBar"/>
<r:RibbonButton Command="{StaticResource EmailCommand}"
r:RibbonQuickAccessToolBar.Placement="InCustomizeMenuAndToolBar"/>
<r:RibbonToggleButton Command="{StaticResource HighGrowthCommand}"
r:RibbonQuickAccessToolBar.Placement="InCustomizeMenuAndToolBar"/>
<r:RibbonToggleButton Command="{StaticResource NearCityCenterCommand}"
r:RibbonQuickAccessToolBar.Placement="InCustomizeMenuAndToolBar"/>
<r:RibbonToggleButton Command="{StaticResource NearDiningCommand}"
r:RibbonQuickAccessToolBar.Placement="InCustomizeMenu"/>
<r:RibbonToggleButton Command="{StaticResource NearShoppingCommand}"
r:RibbonQuickAccessToolBar.Placement="InCustomizeMenu"/>
<r:RibbonToggleButton Command="{StaticResource RecCenterCommand}"
r:RibbonQuickAccessToolBar.Placement="InCustomizeMenu"/>
</r:RibbonQuickAccessToolBar>
</r:Ribbon.QuickAccessToolBar>
Themes & Skins
The WPF Ribbon has a default Windows 7 theme. An Office 2007 Skin can be applied using by
referencing the Office2007Blue ResourceDictionary:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="/RibbonControlsLibrary;component/Themes/Office2007Blue.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Get Started with Ribbon
The preview version of the WPF Ribbon includes all of the above features and more.
Check out the Ribbon on the Office UI Licensing site starting October 28th!
In order to access Ribbon, click on "License the Office UI" and sign the licensing agreement.
The Ribbon download will be available on the page after signing the license.