Archives

Categories


Links




Locations of visitors to this page


El maravilloso universo de la ingenería y desarrollo de software


Mimic Ribbon Panel as 2007 Office-Like with XAML

Apr-282007

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.

 
Posted by Efren Esteban Cruz Anguiano | 1 Comments | Bookmark with:        
Tags: Develop

Links to this Post

Comments

commented on  Friday, June 29, 2007  9:41 AM  by  Great Article
Hi Efren,

Great job!!! That is exactly what I was looking for. I don't need professional control, but something simple and to have more control.

Thanks a log for great job, and sharing your knowledge.

Sincerely,
Vlad.



Name:
URL:
Email:
Comments:

CAPTCHA Image Validation