Menus. Part I

by gleblanc 12. October 2008 12:54

With this post, we are starting a serie of posts dedicated to menus. In this post, we present the basis with a basic menu, though XML driven and, eventually, linked to a status bar. We'll improve it in the forthcoming posts.


Project / source code

As usual, we create a Silverlight application that will host the menu we are building here. Let's assume the application is named Menu1. Visual Studio creates a namespace for the program and, by default, this namespace is named Menu1, as the application.

Our menu is described in a XML file (Menu.xml) and this XML file is inserted as resource into the Silverlight application (Solution Explorer, Add, New element, XML file) :
 <?xml version="1.0" encoding="utf-8" ?>
 <Menu>
  <Item Id="10" Text="Monet" Help="Claude Monet : Thames at Westminster" />
  <Item Id="20" Text="Turner" Help="Joseph Turner : Oxford High Street" />
  <Item Id="30" Text="Renoir" Help="Auguste Renoir : Pont des arts, Paris" />
  <Item Id="40" Text="Pissaro" Help="Camille Pissaro : L'Hermitage" Selected="True" />
  <Item Id="50" Text="Vermeer" Help="Johannes Vermeer : View of Delft" />
 </Menu>

Each menu item must have an Id and a Text attributes and, eventually, a Help sentence (a tooltip eventually displayed in the status bar) and a Selected attribute (the menu item with a Selected attribute is displayed in red and, at program startup, a request is made to the hosting application to respond to that item, as if the user had clicked on that menu item). This makes that menu item the currently selected menu item.

Let's now create the menu, by adding a Silverlight User Control (Solution Explorer, Add, Add new element, Silverlight User Control), that we name Menu.xaml. By default, it's created in the Menu1 namespace (as the hosting program). Since we intend to create a menu that will be easily used in another hosting application, we prefer a specific namespace (here Menu) for the menu (we'll do the same later on for the status bar). This requires two changes : one in the Menu.xaml file (value of x:Class attribute changed to Menu.Menu instead of Menu1.Menu) and one in the Menu.xaml.cs file (namespace Menu instead of namespace Menu1).

In the Menu.xaml file, we delete the Width and Height attributes and force an horizontal StackPanel as container (instead of a Grid). We alse force a Background color with a gradient (it's generally considered nicer) :
 <UserControl x:Class="Menu.Menu"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    >
  <StackPanel x:Name="spMenu" HorizontalAlignment="Stretch" Height="40"
              Loaded="spMenu_Loaded" Orientation="Horizontal" >
   <StackPanel.Background>
    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
     <GradientStop Offset="0" Color="#FEF4C1" />
     <GradientStop Offset="1" Color="#F4E186" />
    </LinearGradientBrush>
   </StackPanel.Background>
  </StackPanel>
 </UserControl>

We create a class (named MenuItem) for a menu item (Solution Explorer, Add, New element, Class), again in the Menu namespace (one line to change in the MenuItem.cs file) :
 namespace Menu
 {
  public class MenuItem
  {
   public int Id { get; set; }
   public string Text { get; set; }
   public string Help { get; set; }
   public bool Selected { get; set; }
  }
 }

In the spMenu_Loaded function, we'll open the Menu.xml file and analyze it using the Linq technology. To do so, need to add a reference (Solution Explorer, Add reference, .NET) to System.Xml.Linq. We also need to add using System.Xml.Linq; to the Menu.xaml.cs file. To analyze our XML file and create a list of MenuItem, we write in Menu.xaml.cs (remember, Help and Selected attributes could be absent : easy for Help, thanks to the null value for a string but a check is necessary for Selected - whatever the value, we consider here, for the sake of simplicity, that the item is selected if the Selected attribute is present) :
 List<MenuItem> tabItems;
 .....
 private void spMenu_Loaded(object sender, RoutedEventArgs e)
 {
  XElement xml = XElement.Load("Menu.xml");
  var listItems = from p in xml.Elements("Item")
                  select new MenuItem
                  {
                   Text = (string)p.Attribute("Text").Value,
                   Id = (int)p.Attribute("Id"),
                   Help = (string)p.Attribute("Help"),
                   Selected=p.Attribute("Selected")!=null ? true : false
                  };
  tabItems = listItems.ToList();
  .....
 }

In the menu bar, each menu item is implemented as a single-cell Grid containing a rectangle (for the color change on MouseOver), a TextBlock (for menu item text) and a vertical Line as separator. We also handle mouse events for each menu item :
 private void spMenu_Loaded(object sender, RoutedEventArgs e)
 {
  .....
  int N = tabItems.Count;
  for (int n=0; n<N; n++)
  {
   TextBlock txtItem = new TextBlock();
   txtItem.Text = tabItems[n].Text;
   txtItem.VerticalAlignment = VerticalAlignment.Center;
   txtItem.HorizontalAlignment = HorizontalAlignment.Center;
   switch (tabItems[n].Selected)
   {
    case true : txtItem.Foreground = new SolidColorBrush(Colors.Red); break;
    case false : txtItem.Foreground = new SolidColorBrush(Color.FromArgb(255, 37, 36, 85));
                 break;
   }
   Rectangle rcItem = new Rectangle(); rcItem.Fill = new SolidColorBrush(Colors.Transparent);
   rcItem.Fill = new SolidColorBrush(Colors.Transparent);
   rcItem.Width = txtItem.ActualWidth +6;
   Grid gridItem = new Grid();
   gridItem.Width = txtItem.ActualWidth+55;
   gridItem.Tag = n;

   Line liSep = new Line();
   liSep.X1 = gridItem.ActualWidth-5; liSep.Y1 = 5;
   liSep.X2 = gridItem.ActualWidth-5; liSep.Y2 = 35; liSep.StrokeThickness = 5;
   liSep.Stroke = new SolidColorBrush(Color.FromArgb(255, 255, 245, 190));

   gridItem.MouseLeave += new MouseEventHandler(c_MouseLeave);
   gridItem.MouseEnter += new MouseEventHandler(c_MouseEnter);
   gridItem.MouseLeftButtonDown += new MouseButtonEventHandler(c_MouseLeftButtonDown);

   gridItem.Children.Add(rcItem);
   gridItem.Children.Add(txtItem); gridItem.Children.Add(liSep);
   spMenu.Children.Add(gridItem);
   .....
  }
At the end of the spMenu_Loaded function, we need to warn the hosting application that the Selected menuItem (here the item with Id 40) has to be activated. To do so, we first need a class (here named MenuEventArgs) derived from EventArgs : Solution Explorer, Add, New element, Class, again in the Menu namespace. Visual Studio creates the MenuEventArgs.cs file, that contains (forgetting a few using at the beginning) :
 namespace Menu
 {
  public class MenuEventArgs : EventArgs
  {
   public int ItemId { get; set; }
  }
 }
In the Menu.xaml.cs file, we need to add a event (here named Click) to warn the hosting application that a menu item has been selected (nSelected containing the ordinal position of the menu item selected in the XML file) :
 public delegate void MenuEventHandler(object sender, MenuEventArgs e);
 public event MenuEventHandler Click;
 .....
 private void spMenu_Loaded(object sender, RoutedEventArgs e)
 {
  .....
  if (nItemSelected!=-1)
  {
   MenuEventArgs args = new MenuEventArgs(); args.ItemId = tabItems[nItemSelected].Id;
   if (Click != null) Click(this, args);
  }
 }
In the mouse event functions, we mark the MouseOver selection or inform the hosting application that a menu item was clicked :
 void c_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
 {
  Grid gridItem = sender as Grid;
  int nItem = (int)gridItem.Tag;
  MenuEventArgs args = new MenuEventArgs(); args.ItemId = tabItems[nItem].Id;
  TextBlock txtItem = gridItem.Children[1] as TextBlock;
  txtItem.Foreground = new SolidColorBrush(Colors.Red);
  if (nItemSelected!=-1) 
  {
   Grid gSel = spMenu.Children[nItemSelected] as Grid;
   TextBlock txtSelItem = gSel.Children[1] as TextBlock;
   txtSelItem.Foreground = new SolidColorBrush(Color.FromArgb(255, 37, 36, 85));
  }
  nItemSelected=nItem;
  if (Click != null) Click(this, args); 
  } 

  void c_MouseEnter(object sender, MouseEventArgs e)
  {
   Grid gridItem = sender as Grid;
   Rectangle rcItem = gridItem.Children[0] as Rectangle;
   rcItem.Fill = new SolidColorBrush(Color.FromArgb(255, 203, 203, 239));
   int nItem = (int)gridItem.Tag;
   .....
  }

  void c_MouseLeave(object sender, MouseEventArgs e)
  {
   Grid gridItem = sender as Grid;
   Rectangle rcItem = gridItem.Children[0] as Rectangle;
   rcItem.Fill = new SolidColorBrush(Colors.Transparent);
   .....
  }
Now, let's add the menu in the hosting application. In Page.xaml, we inform Visual Studio that we'll use Menu (one line to add) :
 <UserControl x:Class="Menu1.Page"
   .....
   xmlns:mnu="clr-namespace:Menu"
   .....
   >
mnu is now the prefix we decide to give to reference our menu. The user inserts for instance the menu in a grid row (in Page.xaml)  :
 <mnu:Menu x:Name="myMenu" Grid.Row="0" Click="myMenu_Click" />
And the myMenu_Click function (in Page.xaml.cs) is something like :
 private void myMenu_Click(object sender, MenuEventArgs e)
 {
  ..... // menu item clicked in e.Id
 }
And now the status bar : we create a Silverlight User Control (StatusBar.xaml), again in the Menu namespace (do not forget the namespace change in StatusBar.xaml.cs). The StatusBar.xaml file becomes :
 <UserControl x:Class="Menu.StatusBar"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      >
  <Grid x:Name="LayoutRoot" Background="White">
   <Border Background="#F4E186" >
    <TextBlock x:Name="txtToolTip" FontSize="10" Foreground="Blue"
               VerticalAlignment="Center"  />
   </Border>
  </Grid>
 </UserControl>
To make the link between the menu and the status bar, we add a property in the Menu class :
 public StatusBar SB { get; set; }
The user inserts a status bar (in Page.xaml) :
 <mnu:StatusBar x:Name="myStatusBar" Grid.Row="2" />
and force the link between the menu and the status bar (for instance in the Loaded function in Page.xaml.cs) :
 myMenu.SB = myStatusBar;

Nothing Silverlight-ish in this menu but we are now ready for more Silverlight-like menus. See you in next posts for that. 

Tags:

Comments

10/14/2008 7:02:01 PM #

Pingback from mgalinks.wordpress.com

2008 October 14 - Links for today « My (almost) Daily Links

mgalinks.wordpress.com

11/12/2008 4:50:39 PM #

Pingback from ebnerj.at

Menüs in Silverlight

ebnerj.at

11/28/2008 9:57:51 PM #

Comments from a neophite.  I can see that your code works from working example at the top of this artile.  However, not sure how you got there.  For example where is "nItemSelected" declared?  Are the mouse event functions completely described here, or is there an assumption of that the functions exist else where?

Consussed Canada

12/11/2008 9:14:27 AM #

nice post!!thanks for the info..that's great

Busby SEO Test United States

1/26/2009 4:39:53 PM #

Really nice post to start off the series.

Big Bus London United Kingdom

2/3/2009 2:23:19 PM #

nice share dude Smile

Inventory Management Software Ukraine

2/11/2009 9:07:49 AM #

Thanks for the great reference post.

Free Service Manual United States

2/14/2009 12:53:39 PM #

It's a good post to read with, it's really worthwhile coming on your page keep it up.

Registry Repair Republic of the Philippines

2/22/2009 7:33:19 AM #

Thanks for the info! Keep it up! Smile

Sell Online United States

2/23/2009 5:37:04 AM #

I don't enjoy using Silverlight much. I think I'm moving all my sites into the new Joomla CMS upgrade. What do you think about Joomla Guys?

Auto Insurance United States

2/26/2009 1:13:49 AM #

Really nice post to start off the series.

law discussion United States

2/26/2009 6:52:18 PM #

this is fantastic reference material.  thank you!

las vegas bankruptcy attorney United States

3/9/2009 1:33:46 PM #

thanks for the code. I'd been looking for that for a months.

Financial Solution United States

3/12/2009 1:08:52 PM #

This is a job well done, thanks for sharing this post, keep it up.

cooldude055 United States

3/17/2009 10:49:21 AM #

I fell blessed that I found your post while searching. This is worth reading. Thanks man!

Real Estate Philippines United States

3/23/2009 5:41:01 PM #

Thnaks for your tutorials, It really helps me understand how Silverlight works and increase my knowledge about other programming.

marina United States

3/25/2009 9:30:56 PM #

interested and will bookmark it, thank you

Make Money Online United States

3/28/2009 11:44:05 PM #

Hi..
thanks for this tutorial..
i enjoy it..

Inventory Management Software United Kingdom

4/13/2009 12:33:23 PM #

Thanks for the tutorial.

goodpeoplegives United States

4/13/2009 12:54:30 PM #

I will bookmark it now.

cash4trends United States

4/13/2009 1:24:25 PM #

Glad I have found this one.

billrainier United States

4/23/2009 10:26:49 AM #

This is a job well done, thanks for sharing this post, keep it up.

Melayu Boleh United States

4/29/2009 6:42:44 AM #

Thanks for the code..at least i learn something new today from u...

swarovski crystal Malaysia

5/15/2009 3:32:29 PM #

Thanks for sharing the useful code here. It really helps me to configure mine.

Marketing Blog United States

6/21/2009 12:36:55 AM #

Thanks for taking the time to share the great post with us

tukang nggame United States

6/30/2009 9:17:17 PM #

This is really good tutorial. I love it

Air Purifier United Kingdom

7/15/2009 1:54:00 AM #

Thanks for the info! Keep it up!

Ebay Sale tips United States

8/6/2009 9:48:20 AM #

How to create flash menus for sony ericsson mobile phones?

Life insurance United States

8/25/2009 2:07:59 PM #

Thanks for writing this. It was very helpful. Keep writing.

Home condition reports United Kingdom

9/13/2009 9:28:30 PM #

Toto ozn�men� o stavu doru.en� je generov�no automaticky.

payday online United States

9/14/2009 6:13:16 AM #

I leave a lot of comments on a lot of blogs each week - but there is one situation where I rarely leave a comment - even if the post deserves it.Good work

payday loans United States

9/14/2009 4:16:48 PM #

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/14/2009 6:54:02 PM #

valuable information and excellent design you got here! I would like to thank you for sharing your thoughts and time into the stuff you post!! Thumbs up

joomla templates United States

9/14/2009 10:34:13 PM #

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 4:09:35 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 7:25:05 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/15/2009 7:49:39 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 11:07:07 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/16/2009 4:44:14 PM #

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

payday loans United States

9/21/2009 8:03:13 AM #

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/21/2009 1:05:23 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/21/2009 5:16:34 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/21/2009 8:55:26 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/22/2009 12:18:44 AM #

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 2:08:05 PM #

How to create flash menus for sony ericsson mobile phones?

SEO United States

9/24/2009 10:52:37 AM #

How menu editor helps in creating menus?

income protection United States

9/25/2009 12:25:11 AM #

Thanks for the great reference post.

auto insurance quotes United States

9/25/2009 10:13:14 PM #

Howdy, i read your blog occasionally and i own a similar one and i was just wondering if you get a lot of spam comments? If so how do you prevent it, any plugin or anything you can advise? I get so much lately it's driving me mad so any assistance is very much appreciated.

Phoenix Bankruptcy United States

9/28/2009 5:40:52 PM #

Thanks for such lovely ideas as they seem to work in my project.

website design United Kingdom

9/29/2009 3:43:26 PM #

Thanks for such lovely ideas

outdoor fireplaces United States

9/30/2009 11:34:01 AM #

Pingback from ebnerj.at

Menüs in Silverlight

Tiffany Rings People's Republic of China

10/7/2009 8:17:59 AM #

Thanks for your great post!!!

Ultimate Wealth Formula X United States

10/10/2009 11:05:16 AM #

very nice and compelling post..you programmers sure is genius..

how to lose weight in 2 weeks 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