Context menu and hierachical menu for Silverlight 4.0

This project started out after I found nothing in the Silverlight open source community that would allow me to use the popup control in a straightforward manner. It is now a fully fledged multilevel menu with support for templating, commanding and many other goodies. I tried to make it as flexible as possible to answer the needs of most Silverlight developers out there while keeping it under 30K(zipped).

Click here to view a demo on the general capabilities of the control in handling shortcut, access keys(try Ctrl+Alt+M), left click, right click and hover events.

In short here is what you get:

  • Nested Menus
  • Pinnable Menus
  • Boundary Detection
  • Animations
  • Keyboard Navigation
  • Shortcuts and Access Keys
  • Data Binding
  • Command Support
  • Vertical Menu Orientation
  • Context Menu
  • Styling
  • Use Existing Themes
  • Scrollable
  • Three State Checkbox
  • Item Template
  • Reusability

Just put an ItemsControl such as a ListBox inside it, specify the name(s) of the trigger control(s) and your menu is ready to fly when you left click, right click or hover the latter.

Any derivative a the ItemsControl like the Treeview can be used as template. However when no control is specified an auto-generated ListBox is used by default.
In the example below a menu consisting of a few menu items and a submenu will popup when the shortcut Ctrl+Alt+M is pressed or when Button1 is right or left clicked:

    <Button Name="Button1" Height="50"/>
    <my:PopupMenu RightClickElements="Button1" LeftClickElements="Button1" AccessShortcut="Ctrl+Alt+M">
        <ListBox>
            <my:PopupMenuItem Header="Menu1" />
            <my:PopupMenuSeparator />
            <my:PopupMenuItem Header="SubMenuHeader1" ImageRightSource="images/arrow.png">
                <my:PopupMenu>
                    <ListBox>
                        <my:PopupMenuItem Header="SubMenu1" />
                    </ListBox>
                </my:PopupMenu>
            </my:PopupMenuItem>
            <my:PopupMenuItem Header="Menu2" />
            <my:PopupMenuItem Header="Menu3" />
        </ListBox>
    </my:PopupMenu>

The example below however uses an XAML free approach to generate a right click menu with a submenu on a Datagrid:

private void GenerateDynamicDemo()
{
    // Add a DataGrid control with some sample data to the layout root
    var data = new ObservableCollection<string>("Item 1,Item 2,Item 3,Item 4,Item 6,Item 7,Item 8".Split(','));
    DataGrid dataGrid1 = new DataGrid() { Margin = new Thickness(50), ItemsSource = data };
    this.LayoutRoot.Children.Add(dataGrid1);

    // Create the submenu
    var spmTimeNow = new PopupMenu();
    spmTimeNow.AddItem("Time Now", null);
    // Create the main menu
    var pm1 = new PopupMenu { AccessShortcut = "Ctrl+Alt+M", OpenOnAccessKeyPressed = true };

    // Add the menu items
    pm1.AddItem("Delete row", delegate { data.RemoveAt(pm1.GetClickedElement<DataGridRow>().GetIndex()); });
    pm1.AddSeparator();
    pm1.AddSubMenu(spmTimeNow, "Get Time ", "images/arrow.png", null, null, false, null); // Attach the submenu pmTimeSub
    pm1.AddSeparator();
    pm1.AddItem("Demo2", delegate { App.Current.Host.NavigationState = "/Views/Demo2.xaml"; });

    // Set dataGrid1 as the trigger element
    pm1.AddTrigger(TriggerTypes.RightClick, dataGrid1);

    // Showing main menu
    pm1.Showing += (sender, e) =>
    {
        pm1.PopupMenuItem(0).Header = "Delete " + dataGrid1.SelectedItem;
        pm1.PopupMenuItem(0).IsVisible =
        pm1.PopupMenuItem(1).IsVisible = pm1.GetClickedElement<DataGridRow>() != null;
    };
    // Showing submenu
    spmTimeNow.Showing += delegate
    {
        spmTimeNow.PopupMenuItem(0).Header = DateTime.Now.ToLongTimeString();
    };
}

To see the compiled outcome click here.

If you used the control and made improvements on it and would like to share it or if you got questions, comments, suggestions or critics then feel free to use my email address(hellozi at live dot com) for this purpose.

Otherwise leaving a review at the bottom would fairly do.

Last edited May 17, 2011 at 10:48 PM by ZiadJ, version 40