Searching on the Internet I required a simple example to utilize a Ribbon Panel as Office 2007, found greats professional controls for this as DevComponent, Professional UI Solutions, SandRibbon, TAdvToolBar, ActiPro or RadRibbonBar; yes, they have great functionally but I only need a simple example for a simple application, exists a Ribbon Control with pure C#, that is compatible with Windows 2000 (An easy way to add a Ribbon Panel Office 2007 style) and only need .NET 2.0, but I can´t modify and to put animation with Xaml or designer tools, I want add great animations and effects with only XAML without write code, after searching and not find anything more, I try developing my own Ribbon Panel with something more than code with XAML using Microsoft Expression Blend, I found a great book about WPF Windows Presentation Foundation Unleashed by Adam Nathan, particularly this post is using as base the Chapter 17 "Layout with Custom Panel", I learning great and simples examples and recommend them this book, In base to this chapter, I have determined extended this sample with style and templates like Office 2007 using Microsoft Expression Blend and little code.
Ok, only let us begin.
Creating Sample Project
Using MS Expression Blend I create a new standard application exe
Next add the class for RibbonPanel, this class permit render items element according to arrange for Office 2007 applications.
using System;
using System.Windows.Controls;
using System.Windows;
namespace SampleRibbon
{
public class RibbonPanel : Panel
{
protected override Size MeasureOverride(Size availableSize)
{
if (Children.Count < 1) return new Size(0, 0);
//Ask the first child for its desired size, given unlimited space
UIElement firstChild = Children[0];
firstChild.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
//if there´s only one child, the panel would like to be exact same size
if (Children.Count < 2) return firstChild.DesiredSize;
//If not, calculate the desired width based on all children
double numRows = Math.Ceiling((Children.Count - 1) / 3d);
double maxWidthForEachRemainingChild = 0;
for (int i = 1; i < Children.Count; i++)
{
//Ask each child for its desired size, given unlimited space
UIElement child = Children[i];
child.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
//Keep track of the maximum width
maxWidthForEachRemainingChild = Math.Max(child.DesiredSize.Width,
maxWidthForEachRemainingChild);
}
return new Size(
//total width
firstChild.DesiredSize.Width + maxWidthForEachRemainingChild * numRows,
//height = desired height of the first child
firstChild.DesiredSize.Height);
}
protected override Size ArrangeOverride(Size finalSize)
{
if (Children.Count < 1) return finalSize;
//Give the first child its desired width but the height of the panel
UIElement firstChild = Children[0];
Point childOrigin = new Point(0, 0);
Size firstChildSize = new Size(firstChild.DesiredSize.Width,
finalSize.Height);
firstChild.Arrange(new Rect(childOrigin, firstChildSize));
if (Children.Count < 2) return finalSize;
//Determine the size for all remaining children
double numRows = Math.Ceiling((Children.Count - 1) / 3d);
Size childSize = new Size((finalSize.Width - firstChildSize.Width) / numRows,
finalSize.Height / 3);
childOrigin.X += firstChildSize.Width;
for (int i = 1; i < Children.Count; i++)
{
UIElement child = Children[i];
child.Arrange(new Rect(childOrigin, childSize));
if (i % 3 == 0)
{
//Start a new column
childOrigin.X += childSize.Width;
childOrigin.Y = 0;
}
else
{
childOrigin.Y += childSize.Height;
}
}
//Fill all the space given
return finalSize;
}
}
}
Additionally I add a class for display image button, this class permit modify template and style for my custom buttons.
using System;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows;
namespace SampleRibbon
{
/// <summary>
/// Clase que contiene los recursos para un botón de imagen
/// </summary>
public class ImageButton : Button
{
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register("Source", typeof(ImageSource), typeof(ImageButton));
public ImageSource Source
{
get { return base.GetValue(SourceProperty) as ImageSource; }
set { base.SetValue(SourceProperty, value); }
}
}
}
On the principal window, put some TabControl, TabItems and GroupBox controls, now the Panel show like this:
After this, add the RibbonPanel and ImageButton controls with some images, don´t miss add namespace on the Window tag.
xmlns:cc="clr-namespace:SampleRibbon"
The elements in tab control are finished; the Ribbon Panel is continuing ugly, right?
Only adds some styles, storyboards and templates with Expression Blend.
Now the Ribbon panel is finish, and looks with animation as wanted!
The complete XAML and source code is here if you would like it.
You put animations, effects, change style and templates easily with XAML and design tools, this characteristic will be many features with which we can play, if you only need a similar style this sample could cover your needs, but if you need more features like context menu, quick access toolbar, application menu, etc, you would be try professional controls or building owns.