These days, I took some time to create a Silverlight menu component, which I'll start using in my projects. It's true that there are much better components in the marketplace, but you can use this one for free, even for commercial purposes, and extend it as you wish.

This article deals first with the features of Silverlight Menu, and also with the implementation details. There are some interesting features, such as MVVM support, XAML support, commanding, checkable menu items, deep menus and basic styling configurations. Although I'm far from being an expert, I hope this article to give readers some notions of building useful components with simple pieces in Silverlight.

The most simple way of using Silverlight Menu is to declare the Menu element directly in the XAML, assigning the MenuItem to a static resource and binding the MenuItemClicked event to some event handler:

This is the simple part. The "hard" part is to declare the MenuItem hierarchy inside Resources section of your page or user control. Notice that the above snippet references the "mnuRoot"MenuItem, so you must start your menu tree with a MenuItem with a x:Key value set to "mnuRoot". As the name says, this is the root for our hierarchy tree, and right below it stand the first level menu items, that fall inside the horizontal top panel. The next level is made up by the children of the first MenuItem level, that will form the vertical menus. The next levels will be all vertical menus, displayed at the right side of their parent MenuItem elements.

Here is the list of MenuItem properties that you can customize:

MenuItems: This is the list of submenus inside the menu item.

Name: The name that uniquely identify the menu item. Notice that each separator also must receive a unique name.

ParentName: [This property is used for internal purposes only.]

Text: The display text for the menu item.

ImagePath: The relative path for the image source displayed at the left of the text. If the path is not found, no image will be displayed. If no image is provided, the application will look for a file located at the ImagesPath property of Menu element + menu item name + ".png".

IsCheckable: Boolean property that defines whether the menu item can be checked or not.

IsChecked: If the menu item is checkable, and if the menu item is checked, a "checked.png" image will be displayed, otherwise no image is displayed.

Level: [This property is used for internal purposes only.]

MenuGrid: [This property is used for internal purposes only.]

Below there is a MenuItem hierarchy for our example (notice that this example was taken from Visual Studio 2010 menus). At first, this seems to be too much work to do, but since it is XAML, you can make use of Intellisense to discover which properties you can customize for each MenuItem:

In the above example, you must implement the MenuItemClicked event, otherwise you would not be able to take action when the user clicks a specific menu item. Below there is an example of implementation of this event, that shows a simple messagebox with the name of the menu item and also informs when a checkable menu has been checked/unchecked.

If you don't know the MVVM (Model View View Model) pattern, here is a very simple explanation: in the above example, we created the menu hierarchy directly in the view (the MainPage.xaml file) and we implemented the MenuItemClicked directly in the code behind of the view (the MainPage.xaml.cs file). In the MVVM pattern, on the other hand, we wouldn't use the view for this. Instead, we would configure the view (the MenuTestView.xaml file) so that the menu properties would be bound to properties from another class (the View Model, represented by the MenuTestViewModel.cs file).

The following diagram shows the MVVM components in a generic scenario:

Back to our application: in order to use the MVVM mode, comment the following line and enable the application to use MenuTestView as the startup:

Open the MenuTestView view and notice the differences for the MVVM style: first, we must define the ImagesPath, because the View is located at a "\Views" folder, and this changes the relative path for the images. Then we must configure the MenuItem property to bind to some property on the ViewModel side (the MVVMMenuItem, in our case). And finally there is the Command property, that is bound to the MenuCommand property on the ViewModel side. Notice that the MenuCommand has the same effect as implementing the MenuItemClicked event, with the difference of being implemented in the ViewModel instead of in the code behind:

Finally, we have the implementation for the Command property. Notice that in this type of binding, the DoMenuCommand method reference is stored when the Menu element is created (notice that the DoMenuCommand is not fired yet):

Depending on the layout styles you are using for your Silverlight application, the default styles of Silverlight Menu can break the visual identity of your web application and produce an undesirable result. You can handle this problem by configuring the Menu to use a different set of brushes and colors, as you want.

The following XAML excerpt shows how to configure Silverlight Menu for a "black" style:

There are some cases when you need to add submenus dynamically. This is the case of "Recent Files" of almost every desktop application that deals with documents. Silverlight Menu is prepared to deal with this scenario:

The only requirement is that you call the AddMenuItem method of the Menu class whenever you want to add an sub item to a menu item (because the AddMenuItem will refresh the menu tree automatically):

As you have seen, this Silverlight Menu is made of simple Silverlight elements, so forgive me if it doesn't give the functionality you want. I'd love to hear your feedback about it, especially if you use it in your projects. As I said before, this component will be part of my future projects, so I'm interested in enhancing it as much as I can, and that's why your feedback is so important.

Share

About the Author

Marcelo Ricardo de Oliveira is a senior software developer who lives with his lovely wife Luciana and his little buddy and stepson Kauê in Guarulhos, Brazil, is co-founder of the Brazilian TV Guide TV Map and currently works for ILang Educação.

He is often working with serious, enterprise projects, although in spare time he's trying to write fun Code Project articles involving WPF, Silverlight, XNA, HTML5 canvas, Windows Phone app development, game development and music.

Best Web Dev article of March 2013
Best Web Dev article of August 2012
Best Web Dev article of May 2012
Best Mobile article of January 2012
Best Mobile article of December 2011
Best Mobile article of October 2011
Best Web Dev article of September 2011
Best Web Dev article of August 2011
HTML5 / CSS3 Competition - Second Prize
Best ASP.NET article of June 2011
Best ASP.NET article of May 2011
Best ASP.NET article of April 2011
Best C# article of November 2010
Best overall article of November 2010
Best C# article of October 2010
Best C# article of September 2010
Best overall article of September 2010
Best overall article of February 2010
Best C# article of November 2009

Thanks for work and posting article. It's be best one I've seen on the subject.

I just downloaded the code, and I am getting a 'The Property "MenuItems" can only set once.' error in the XAML. Has anyone else seen this problem? The code compiles and runs using Silverlight 5, but the Designer says "Invalid Markup" and points to:

I'm experiencing the same issue using Visual Studio 2012 with the SilverlightMenu Sln included with the source. This seems like a terrific Menu, but not being able to view the xaml preview is a deal breaker for me.

To create a bottom-up menu, you should do a lot of changes in the project. Instead of modifying it, I would recommend using the Silverlight Menu4U[^] that I created more recently and supports the feature you want.

Hi,
i am using your control one of the navigation application (Silverlight default template, SL 4.0), till the opened menuitem are in top border, they are clickable however when it's above page border it's not clickable however view able if you play with canvas.zindex property. do you have any solutions for same?

"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David CrowNever mind - my own stupidity is the source of every "problem" - Mixture

Hi, First off let me say that I love the menu. I have a question about adding items after the fact. I am using MVVM and loading the items in my ViewModel constructor which seems to be working fine. However, when I try to add an item outside the constructor it does nto get added. For instance, I need some menu items to be loaded in a callback from a service call they gets a list of available plugins. Once the plugins load, I need to add menu items for them. Whenever I try this, nothing gets added. I even tried fully populating the menu in the callback and it fails. Am I missing something?

I downloaded your code and used in a typical scenario Silverlight application: an user enters a login page and then he clicks Login button which brings him to the main page with your menu on top.
However, when I logout and then login again, I get this error:

Hi, First of all thanks for such a nice menu.
I am adding menu items dynamically to the menuitems. But strangely when I try to clear or remove items from it the collection gets cleared but menu remains on the page.