Click here to Skip to main content
Click here to Skip to main content
Go to top

Localized Ribbon Control for Windows Forms Applications

, 5 Oct 2010
Rate this:
Please Sign up or sign in to vote.
Create a localized Ribbon control for Windows Forms Applications
Localization Sample

Be.HexEditor Sample

Introduction

In this article, I will show how you can add a localized Ribbon control to a Windows Forms application. I'm using the Windows integrated Ribbon that releases with Windows 7, but is also available for Vista and Windows Server 2008, when relevant service packs and updates are installed.

Requirements

Operating systems containing Windows Ribbon Framework

  • Windows 7
  • Windows Vista with SP2 and Platform Update for Windows Vista
  • Windows Server 2008 R2
  • Windows Server 2008 with SP2 and Platform Update for Windows Server 2008

Additionally for Development

  • Visual Studio 2010 must be installed
  • Windows 7 SDK must be installed
  • RibbonGenerator custom tool must be installed (Included in download "\RibbonLocalization\setup\RibbonGenerator.Setup.msi")

Windows Ribbon Framework and .NET Wrapper

There are many other Ribbon libraries out there. Most of them are commercial versions - for example from Infragistics, but for me I wanted a free one. Also because Windows Forms adopts Windows controls in general, I decided to use the Windows integrated one.

If you want to get more technical information about the Ribbon, look into MSDN: Windows Ribbon Framework.

Windows Ribbon is an unmanaged control offering a COM interface that can be adopted in .NET using custom COM wrappers. I found an appropriate solution at CodePlex (http://windowsribbon.codeplex.com/) with many samples. It's a very impressive work, but also the code is transportation from C++ to C# and therefore the object model of the wrapper is not .NET like. For that reason, I refactored it a little bit, but first let's take a look at how the Ribbon can be added to your application.

Using the Ribbon

Before you read this, you should be familiar with the original .NET Wrapper on CodePlex.

Now I will show you how you can use my refactored .NET Wrapper with the RibbonGenerator custom tool to add a Ribbon to your Windows Forms application. Please do not forget to consider the software requirements from above and that the RibbonGenerator custom tool must be installed.

Add Ribbon XAML(RibbonMarkup.xml) and Localization Files (RibbonMarkup.resx)

For more details about Ribbon XAML, look at MSDN or the CodePlex samples mentioned above.

  1. The localization information for the Ribbon text. The file name must be equal to the Ribbon XAML file
  2. The Ribbon XAML file
  3. The Ribbon embedded resource generated by custom tool
  4. The Ribbon log file generated by custom tool
  5. The custom tool name to generate *3 and *4

How Localization Works

Ribbon UI information must be defined in the Ribbon XAML file and localization information in the ResX file. The custom tool is searching for "{Resource" tags in the XAML file and replacing it using information from ResX file. Multiple .ribbon files are generated - one for each ResX file.

Define localized text inside Ribbon XAML using {Resource:<ResourceKey>} notation.

Add localized resources to ResX file

Adding the Ribbon Control to your Form

The easiest way is to add the Ribbon.dll to your toolbox. You can find it in the download looking there: "\bin\Ribbon.dll"

Use drag and drop from toolbox

In the Visual Studio designer, the Ribbon control will look like this:

Specify the Ribbon UI in the Ribbon control properties

In the properties of the Ribbon control, we must specify the ".ribbon" file generated by the RibbonGenerator custom tool. The file must be an embedded resource in your application. You can find it under your Ribbon XAML file.

Result looks like...

Let's see how the result looks like. In our sample, we have two Ribbon resources: Default and German.

Localized by default culture

Specify culture information

In order to use a localized Ribbon, the application's current culture must be set by changing the CurrentCulture property of the current thread.

Localized by German culture

Refactoring the .NET Wrapper

I refactored the original .NET Wrapper to be more .NET like, because it has some design issues I dislike:

  • Localization support is not implemented
  • A separate unmanaged DLL containing the Ribbon resources is created and must be deployed within the application directory
  • A form containing the Ribbon must implement an interface called IRibbonForm
  • Ribbon class does not derive from Control class
  • Ribbon object must be initialized directly in Form code
  • Visual Studio designer is not supported generally
  • Ribbon DLL is created using Pre-build event, so ribbon is recreated every time the application builds.
  • Automatic build and deployment can make a lot of trouble

To solve that, I did some changes to the .NET Wrapper and created the RibbonGenerator custom tool:

  • The Ribbon UI (".ribbon") is included as embedded resource now and must not be deployed as separate DLL
  • There is one embedded resource file for each localized version to support multi-languages
  • Ribbon class derives from Control class now to add minimum Visual Studio designer support and to make IRibbonForm interface obsolete
  • The ".ribbon" file will only be updated when the RibbonGenerator custom tool runs.
  • The RibbonGenerator custom tool also considers ResX files to add localization support.

The Modified .NET Wrapper (Ribbon.dll)

I want to give you a small technical overview of the changes I have made.

Make Ribbon Class Deriving from Control

The Ribbon class now derives from Control class. The advantage is that the object model is more .NET like and the designer can be used. Also, no IRibbonForm interface must implemented by the form containing the Ribbon.

Making IRibbonForm interface obsolete

IRibbonForm interface of the original version had to be implemented for two reasons: The form's handle must be retrieved and the form must be notified on Ribbon height changes to update the position of anchoring controls. Now in my .NET Wrapper, the height update is forced on the Ribbon control and the control itself can return the form's handle.

[Browsable(false), DesignerSerializationVisibility
		(DesignerSerializationVisibility.Hidden)]
public IntPtr WindowHandle
{
get
{
var form = this.Parent as Form;
return form.Handle;
}
}

Disable Rendering

The .NET Ribbon control works as a place holder and injects the Windows Ribbon in the form. It does not contain any rendering information, but knows the height of the Ribbon. Therefore, we can disable control rendering.

this.SetStyle(ControlStyles.UserPaint, false);
this.SetStyle(ControlStyles.Opaque, true);

The Ribbon is docking always on top of the form, so we set that in the constructor and override the Dock property to disable changes.

public Ribbon()
{
	base.Dock = DockStyle.Top;

....

[DefaultValue(typeof(DockStyle), "Top")]
public override DockStyle Dock
{
	get
	{
		return base.Dock;
	}
	set
	{
	}
}

Ribbon Control is Loading the UI

The Ribbon control reads an embedded resource file and saves that into the user's temp directory to load the Ribbon UI.

void InitFramework(string ribbonResource, Assembly ribbonAssembly)
{
	string path = Path.Combine(Path.GetTempPath(), "RibbonDlls");
	_tempDllFilename = Path.Combine(path, Path.GetTempFileName());
	var buffer = GetLocalizedRibbon(ribbonResource, ribbonAssembly);

	File.WriteAllBytes(_tempDllFilename, buffer);

	// if ribbon DLL exists, use it
	if (File.Exists(_tempDllFilename))
	{
		// load ribbon from ribbon DLL resource
		InitFramework(DefaultResourceName, _tempDllFilename);
	}
}

RibbonGenerator Custom Tool for .ribbon File Generation

The custom tool does the same job as the pre-build event script in the CodePlex samples. In short: It generates the ".ribbon" files. More: The custom tool creates one .ribbon file for each .ResX file to support localization. It needs Windows 7 SDK binary tools be present on the system, because it just creates and executes batch files. The template of the batch file will be created on the first run in the user's app data folder. This template can be customized by you.

Template.bat

If the RibbonGenerator custom tool will not work on your system but all requirements are installed, probably you need to customize the template.bat file.

"C:\Program Files\Microsoft SDKs\Windows\v7.0\bin\UICC.exe"
	"{XmlFilename}" "{BmlFilename}" /res:"{RcFilename}"
"C:\Program Files\Microsoft SDKs\Windows\v7.0\bin\rc.exe" /v "{RcFilename}"
cmd /c "("%VS100COMNTOOLS%..\..\VC\bin\vcvars32.bat") &&
	("%VS100COMNTOOLS%..\..\VC\bin\link.exe"
	/VERBOSE /NOENTRY /DLL /OUT:"{DllFilename}" "{ResFilename}")"

As you can see, the template.bat contains process steps that will execute while the custom tool is running. If you delete the template.bat file, it will be recreated on the next run. To ensure, that the RibbonGenerator will work correctly, install the Windows 7 SDK first, otherwise delete or customize the template.bat file.

Points of Interest

I was playing with the CodePlex library and thinking about implementing the Ribbon in future versions of Be.HexEditor. I figured out that localization is not so easy to implement in a short time, so probably it will be helpful to you.

History

  • 16th September, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Bernhard Elbl
Software Developer (Senior) bemento
Germany Germany
No Biography provided

Comments and Discussions

 
QuestionMy vote of 5 PinmemberRingo Deng21-Nov-12 18:41 
QuestionCustom tool error: Generation failed. Error: uicc.exe failed to generate .bml or .rc file! Pinmemberbalagp24-May-12 17:12 
Questionhow to use sir.... Pinmemberbalagp11-May-12 22:49 
QuestionRibbon Control that works on XP PinmemberMember 376612120-Dec-11 3:36 
QuestionQuick Access Toolbar PinmemberCélio4-Nov-11 8:09 
AnswerRe: Quick Access Toolbar PinmemberBernhard Elbl4-Nov-11 8:57 
GeneralRibbonGenerator not found PinmemberRoland Simon21-Nov-10 10:55 
GeneralRe: RibbonGenerator not found PinmemberBernhard Elbl21-Nov-10 19:41 
GeneralRe: RibbonGenerator not found PinmemberRoland Simon14-Dec-10 5:10 
GeneralRe: RibbonGenerator not found PinmemberBernhard Elbl14-Dec-10 22:03 
GeneralRe: RibbonGenerator not found PinmemberRoland Simon20-Jan-11 10:50 
GeneralRe: RibbonGenerator not found PinmemberBernhard Elbl20-Jan-11 20:00 
GeneralRe: RibbonGenerator not found PinmemberRoland Simon24-Jan-11 7:45 
GeneralRe: RibbonGenerator not found PinmemberBernhard Elbl24-Jan-11 20:13 
GeneralNICE!! PinmemberZac Greve15-Oct-10 13:50 
GeneralRe: NICE!! PinmemberBernhard Elbl15-Oct-10 20:09 
QuestionBlock out the user name? PinmemberCorey Fournier17-Sep-10 5:59 
AnswerRe: Block out the user name? PinmemberBernhard Elbl17-Sep-10 8:39 

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

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

| Advertise | Privacy | Mobile
Web01 | 2.8.140922.1 | Last Updated 6 Oct 2010
Article Copyright 2010 by Bernhard Elbl
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid