Menus, part II : multi-level drop-down menu

by gleblanc 26. October 2008 14:43

In this post, we will implement a multi-level drop down menu, ie eventually with any number of sub-menus. The drop-down menu presented here is XML driven, though without animation, as possible with Silverlight. We'll add animation effects in the forthcoming post.


Project / source code

The art-work initially displayed is "Tomorrow" from Jean-Yves Tanguy, a French painter who became an American citizen.

Our menu is XML-driven, as a set of Item tags. An Item tag can itself contain any number of Item tags (corresponding to any number of sub-menus and any number of sub-menu items) : 

<?xml version="1.0" encoding="utf-8" ?>
<Menu>
  <Item Id="10" Text="Antarctica" />
  <Item Id="20" Text="Europe" >
    <Item Id="201" Text="Italy" >
      <Item Id="2011" Text="Florence" />
      .....
    </Item>
    <Item Id="202" Text="France" >
      <Item Id="2021" Text="Paris" />
      <Item Id="2022" Text="French riviera" >
        <Item Id="20221" Text="Nice" />
        <Item Id="20222" Text="Monaco" >
          <Item Id="202221" Text="Monaco" />
          <Item Id="202222" Text="Monte-Carlo" />
        </Item>
        <Item Id="20223" Text="Saint-Jean Cap Ferrat" />
      </Item>
      <Item Id="2023" Text="Provence" />
    </Item>
    .....
  <Item Id="30" Text="America" >
  .....
  </Item>
  .....
  <Item Id="50" Text="Oceania" />
</Menu>

For each menu item, you need to provide an Id value as well as a Text. A Click event is raised whenever the user clicks on a menu item (the Id can then be retrieved from the second parameter of the event handling function).

As usual, we create a Silverlight application that will host the drop-down menu we are building here. Let's assume the application is named UseDropDownMenu. Visual Studio creates a namespace for the program and, by default, this namespace is named UseDropDownMenu, as the application. We first create a DropDownMenu XAML file and we specify glMenu as namespace (thus, as seen in the previous post, one change in the xaml file and another one in the xaml.cs file, these two files being created by Visual Studio).

In the hosting Silverlight application, we need to reserve space for the main menu (top horizontal bar, whose height is 30 pixels). The menu part must remain on top (this is why the Canvas.ZIndex attribute, applicable to a Grid container, is given a large value) :
 <UserControl x:Class="UseDropDownMenu.Page"
    .....
    xmlns:mnu="clr-namespace:glMenu"
    ..... >
    <Grid x:Name="LayoutRoot" Background="White">
     <Grid x:Name="menuGrid" Canvas.ZIndex="99" >
      <mnu:DropDownMenu x:Name="myMenu" Click="myMenu_Click" />
     </Grid>
     <Grid x:Name="g">
      .....        user grid here
     </Grid>
    </Grid>
 </UserControl> 

In the DropDownMenu.xaml file, we give the XAML description of the main menu bar (implemented as an horizontal StackPanel). Sub-menus (that are vertical StackPanel) will be dynamically added, as needed (and later on removed) :
 <UserControl x:Class="glMenu.DropDownMenu"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    >
  <Grid x:Name="menuGrid" HorizontalAlignment="Stretch" VerticalAlignment="Top" >
   <StackPanel x:Name="spMainMenu" Loaded="spMainMenu_Loaded"  Orientation="Horizontal"
               Height="30" >
    <StackPanel.Background>
     <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
      <GradientStop Offset="0" Color="#FEF4C1" />
      <GradientStop Offset="1" Color="#F4E186" />
     </LinearGradientBrush>
    </StackPanel.Background>
   </StackPanel>
  </Grid>
 </UserControl>


Thanks to Linq, it's easy to retrieve the Item children (just the children, not the grand-children) of a specific Item (an XElement within the XML file) :
 List<MenuItem> getMenuItems(XElement xml)
 {
  var lstItems = from p in xml.Elements("Item")
                 select new MenuItem
                 {
                  Text = (string)p.Attribute("Text").Value,
                  Id = (int)p.Attribute("Id"),
                  hasSubMenu = p.HasElements,
                  XElem = p
                 };
  return lstItems.ToList();
 }

MenuItem is a class created to hold attributes of a menu item. Menu is another class created to hold attributes of a menu (main menu or sub-menu). Menus displayed at one time are kept in a list of menus :
 List<Menu> lstMenus = new List<Menu>();

The main menu is created at Loaded time while sub-menus are created (and removed) as needed. A menu is first created in memory (each menu item is implemented as a Grid containing a rectangle - to mark MouseOver - and a TextBlock for the Text) :
 void PrepareMenuPresentation(Menu mnu) 
 {
   .....
  int N = mnu.lstMenuItems.Count;
  for (int n = 0; n < N; n++)
  {
   TextBlock txtItem = new TextBlock(); 
   .....    
   Rectangle rcItem = new Rectangle(); 
   ......
   Grid gridItem = new Grid();
   .....  
   gridItem.MouseLeave += new MouseEventHandler(item_MouseLeave);
   gridItem.MouseEnter += new MouseEventHandler(item_MouseEnter);
   gridItem.MouseLeftButtonDown += new MouseButtonEventHandler(item_MouseLeftButtonDown);
   gridItem.MouseMove += new MouseEventHandler(item_MouseMove);
   gridItem.Children.Add(rcItem); gridItem.Children.Add(txtItem);
   mnu.StackPan.Children.Add(gridItem);
  }
   .....   
 } 


The mouse events are handled to control navigation from menu items to menu items (and, remember, sub-menus are dynamically added or removed).

Our code (300 lines) is not that long and complex but it would be too annoying - and useless - to explained it here line by line. Moreover, I tried to document the code as well as I could.

Tags:

Comments

10/28/2008 4:33:53 AM #

Trackback from Community Blogs

Silverlight Cream for October 27, 2008 -- #408

Community Blogs

11/8/2008 12:25:17 PM #

Cool Gerard. I like your writing very much.

Faisal bd

7/14/2009 3:04:27 PM #

Very interesting topic will bookmark your site to check if you write more about in the future.

Christian Dior United States

8/5/2009 6:45:05 AM #

A SUPPORTED BY THE DEVELOPER TOOLS? It was interesting. You seem very educated in your field.

payday loans United States

8/5/2009 6:45:08 AM #

Such a usefule blog�wow !!!!

payday loans United States

8/11/2009 3:40:21 AM #

As a Newbie, I am always searching online for articles that can help me. Thank you

cash loans United States

8/11/2009 3:40:24 AM #

Your blog is so informative � keep up the good work!!!!

cash loans United States

8/14/2009 5:36:56 PM #

I didn't know that!

Learn German United States

9/7/2009 2:25:27 PM #

We are a group of volunteers and starting a new initiative in a community. Your blog provided us valuable information to work on. You have done a marvellous job!

Property Lawyer United Kingdom

9/11/2009 11:46:18 AM #



I recently came across your blog and have been reading along. I thought I would leave my first comment. I love the way you write post!

Web design United Kingdom

9/15/2009 7:41:25 AM #

I havent any word to appreciate this post.....Really i am impressed from this post....the person who create this post it was a great human..thanks for shared this with us.

payday online United States

9/15/2009 9:11:08 AM #

Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts.Any way Ill be subscribing to your feed and I hope you post again soon

payday online United States

9/16/2009 6:44:45 PM #

Easy option to get useful information as well as share good stuff with good ideas and concepts

payday loans United States

9/16/2009 8:27:40 PM #

Pretty good post.

soccer live score United States

9/16/2009 8:28:39 PM #

Your blog is so informative

live score board United States

9/16/2009 8:29:16 PM #

As a Newbie, I am always searching online for articles that can help me.

live score service United States

9/16/2009 8:30:00 PM #

I didn't know that!

live scoring United States

9/16/2009 8:30:43 PM #

Such a usefule blog�wow !!!!

live scores online United States

9/16/2009 8:31:40 PM #

I have really enjoyed reading your blog posts.

soccer scores United States

9/16/2009 8:32:20 PM #

Nice post

kamagra tablets wholesale United States

9/16/2009 8:32:52 PM #

I am always searching online for articles that can help me.

best price kamagra United States

9/16/2009 8:33:16 PM #

thanks for shared this with us

cheap viagra United States

9/16/2009 8:33:42 PM #

Easy option to get useful information as well as share good stuff with good ideas and concepts

kamagra buy United States

9/16/2009 8:34:02 PM #

Great website

cheapest kamagra United States

9/21/2009 8:47:41 PM #

We are a group of volunteers and starting a new initiative in a community. Your blog provided us valuable information to work on.You have done a marvellous job!

payday loans United States

9/23/2009 5:27:53 PM #

Hey very nice blog!! Man .. Beautiful .. Amazing .. I will bookmark your blog and take the feeds also...

payday loans United States

9/23/2009 5:27:55 PM #

You made some good points there. I did a search on the topic and found most people will agree with your blog.

payday loans United States

9/28/2009 4:35:36 PM #

I have never read such a lovely post and I am coming back tomorrow to continue reading.

web design United Kingdom

9/28/2009 4:45:31 PM #

You are a real master of coding.

Russian translation United States

9/29/2009 3:25:35 PM #

You are a real master of coding.

colorado outdoor fireplaces United States

9/30/2009 11:33:50 AM #

Cool Gerard. I like your writing very much.

Tiffany Rings People's Republic of China

10/2/2009 4:15:56 PM #

Hi, I can�t understand how to add your site in my rss reader. Can you Help me, please Smile

personal loan United States

10/2/2009 4:16:01 PM #

Great articles & Nice a site�.

personal loan United States

10/9/2009 6:36:26 PM #

Thanks for providing such precious info.

Web Design United Kingdom

10/10/2009 1:22:46 AM #

You made some good points there. I did a search on the topic and found most people will agree with your blog.

cash loans United States

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen

About the author

Gerard Leblanc is the author of several books (in french) on C++, C#, .NET and Silverlight (Eyrolles, Paris as publisher). See www.gleblanc.eu as the companion web site for these books (included sample programs).
He is Microsoft MVP for Silverlight.

MVP logo