Scott Guthrie announced the new Ribbon Control a few days ago, so I thought give it a shot to see how it works.

Referencing the Ribbon

First, create a window and import the control’s namespace. If you’re using the dll provided in RibbonBinaries folder, you can not use namespace mapped to Xmlns! This is because the file “AssemblyAttrs.cs” is not included in the project file, so the Xml namespace won’t map to CLR namespace correctly. To fix this, you should recompile the control. Open the project file and add the existing “AssemblyAttrs.cs” file to the project, remove the redundant code that is duplicated in AssemblyInfo.cs, and build. Use the newly compiled dll file instead. After doing so, you can import the mapped namespace:

1
2
3
4
5
6
7
8
<Window x:Class="MSRibbon.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:rib="http://schemas.microsoft.com/wpf/2008/ribbon"
Title="Main Window" Height="600" Width="800">
<DockPanel>
</DockPanel>
</Window>

Office UI Design guidelines clearly says that you SHOULD ALWAYS dock the Ribbon to the top of your window.

1
2
3
4
5
<DockPanel>
<rib:Ribbon DockPanel.Dock="Top">

</rib:Ribbon>
</DockPanel>

Adding Controls to Ribbon

Next thing would be to add a few controls to our ribbon. In this new ribbon, unlike other ribbons in the market, the approach to add controls to the ribbon is more View-Model centric, meaning you always use a RibbonCommand, which is a subclass of RoutedCommnad, to specify a tool’s Title, Description, Tooltip, Icon, etc. Let’s create some Ribbon Commands now:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<Window.Resources>
<rib:RibbonCommand x:Key="CopyCommand" LabelTitle="Copy"
SmallImageSource="Images\Copy-small.png"
LargeImageSource="Images\Copy-large.png"
ToolTipTitle="Copy"
ToolTipDescription="Copies the selected data into clipboard."
Executed="CopyCommand_Executed" />
<rib:RibbonCommand x:Key="PasteCommand" LabelTitle="Paste"
SmallImageSource="Images\Paste-small.png"
LargeImageSource="Images\Paste-large.png"
ToolTipTitle="Paste"
ToolTipDescription="Pastes the data from the clipboard."
Executed="PasteCommand_Executed" />
<rib:RibbonCommand x:Key="CutCommand" LabelTitle="Cut"
SmallImageSource="Images\Cut-small.png"
LargeImageSource="Images\Cut-large.png"
ToolTipTitle="Cut"
ToolTipDescription="Cuts the data from the window."
Executed="CutCommand_Executed" />
<rib:RibbonCommand x:Key="ClipboardGroupCommand" LabelTitle="Clipboard" />
</Window.Resources>

We can use these commands to build up our ribbon’s UI, in a much simpler and cleaner way:

1
2
3
4
5
6
7
8
9
<rib:Ribbon DockPanel.Dock="Top" >
<rib:RibbonTab Label="Home">
<rib:RibbonGroup Command="{StaticResource ClipboardGroupCommand}">
<rib:RibbonButton Command="{StaticResource CutCommand}" />
<rib:RibbonButton Command="{StaticResource CopyCommand}" />
<rib:RibbonButton Command="{StaticResource PasteCommand}" />
</rib:RibbonGroup>
</rib:RibbonTab>
</rib:Ribbon>

Ribbon

So far we have an incomplete Ribbon control on our hands. Let’s move ahead and see how we can satisfy other ribbon’s requirements.

Application Menu and RibbonWindow

Switching to a Ribbon Window as simple as changing the type of your Window to RibbonWindow and you’re all set. As for the Application Button goes, you can set it through ApplicationMenu property of your Ribbon control:

1
2
3
<rib:Ribbon.ApplicationMenu>
<rib:RibbonApplicationMenu Command="{StaticResource ApplicationCommand}" />
</rib:Ribbon.ApplicationMenu>

Of course you need a RibbonCommand for the application button as well. So, just set the image in a RibbonCommand and run:

1
2
3
<rib:RibbonCommand x:Key="ApplicationCommnad"
LargeImageSource="Images\App.png"
SmallImageSource="Images\App-small.png" />

To my surprise, if you only add a 32 x 32 image to your application button, it will show up as empty in Aero skin! You also need to add a Small image (16 x 16) to make it work in Aero skin. This obviously violates many of the the Office UI Licensing rules that states The Application Button MUST be round or The Application Button MUST have approximately a 36 pixel diameter. Both 16 x 16 image size and application button shape in Aero which looks like a rectangle with round edges, violates the mentioned rules. There are other things that violates the Office UI Licensing like Group Labels MUST have a background color that is distinct from the background group, which as you can see in the above picture, it is not the case, and the Group Label “Clipboard” has the same background as the group. All these makes me wonder if we can use this skin at all!!

So, let’s change the skin to a non-violating skin, add some application actions to our Application Menu and see how the Ribbon control looks like. To change the skin via Xaml, merge the skin resource you want with you application resources:

1
2
3
<Application.Resources>
<ResourceDictionary Source="/RibbonControlsLibrary;component/Themes/Office2007Blue.xaml"/>
</Application.Resources>

Now, let’s add some application related actions to our Application Menu. We’ll add application wide actions like New Open, Close and Save for the purpose of this demo. To add to Application Menu items in Xaml, add it to Items collection of you ApplicationMenu object. ApplicationMenu also has a Footer property which you can add other controls to.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<rib:Ribbon.ApplicationMenu>
<rib:RibbonApplicationMenu Command="{StaticResource ApplicationCommnad}">
<rib:RibbonApplicationMenu.Items>
<rib:RibbonApplicationMenuItem Command="{StaticResource NewAppCommand}" />
<rib:RibbonApplicationMenuItem Command="{StaticResource OpenAppCommand}" />
<rib:RibbonApplicationMenuItem Command="{StaticResource CloseAppCommand}" />
<rib:RibbonApplicationMenuItem Command="{StaticResource SaveAppCommand}" />
<rib:RibbonSeparator />
<rib:RibbonApplicationMenuItem Command="{StaticResource ExitAppCommand}" />
</rib:RibbonApplicationMenu.Items>
<rib:RibbonApplicationMenu.Footer>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<rib:RibbonButton Command="{StaticResource OptionsAppCommand}" Margin="5" />
<rib:RibbonButton Command="{StaticResource ExitAppCommand}" Margin="5" />
</StackPanel>
</rib:RibbonApplicationMenu.Footer>
</rib:RibbonApplicationMenu>
</rib:Ribbon.ApplicationMenu>

Due to the fact that we can reuse RibbonCommands in multiple places, we’re sharing our ExitAppCommand both in ApplicationMenu footer and as a Application menu item. Here’s how it looks:

AppMenu

Localization

Like standard WPF Controls you should be able to set the FlowDirection of RibbonWindow to RightToLeft to mirror the window and its content, but if you do so, the control will not work correctly. Even if you set the flow direction of the ribbon control that resides in a RibbonWindow, there are rendering problems. If you need to use the RibbonControl in a RightToLeft reading order, you can use a normal WPF Window which renders fine and mirrored Riboon will look fine.

Control behavior is correct when hosted in a normal WPF Window

Control Renders incorrectly over the RibbonWindow's Non-client area

You can use any standard localization procedure you do with normal WPF controls. Since almost everything you need to localize is a RibbonCommand, you only need to keep your commands localizable. I couldn’t find clues on how to describe internal Ribbon strings, which apparently you can not.

Summary

Recently provided Ribbon control is a lightweight implementation office Ribbon control. Although this is a great control, it lacks functionality in the area of Localization. This is an initial release and I hope it gets better by next versions. Remember to completely read the Office UI Guideline document before you start developing application that uses a Ribbon control.

You can download related files here.