views:

2301

answers:

2

I am creating a contextmenu that should contain a listing of all folders, subfolders, and files in a chosen folder. I want the menu to open the files and folders when they are clicked, but the click event doesn't register if the menuitem has subitems.

void Foo(string Title)
{
    MenuItem = new MenuItem(Title);
    MenuItem.Click += new EventHandler(MenuItem_Click);
    ContextMenu.MenuItems.Add(MenuItem);
}

void MenuItem_Click(object sender, EventArgs e)
{
    MessageBox.Show("This box will only show when menuitems without subitems are clicked");
}

How can I make the click event fire even if the menuitem has subitems?

+2  A: 

It sounds like a menu may not be the most appropriate UI widget here. I believe the reason you don't get a click event raised is that menu items with submenus are assumed to only expand their children when clicked, rather than executing any other action.

That's likely to be the assumption of the user, too.

This behaviour is mentioned in the documentation for MenuItem.Click:

Note: If the MenuItems property for the MenuItem contains any items, this event is not raised. This event is not raised for parent menu items.

Jon Skeet
It is supposed to be a tiny application that gives access to most used folders, files, websites, etc very easily. My idea is a tray icon with a right click menu, as I cannot see any other controls that would be both easily accessed and hidden when not in use. There is no way to make the event raise, then?
Erlend D.
Not without a grotty hack, I suspect. You could add a "leaf" menu item under each directory with the name "[This directory]" though. How would you detect the difference between a user clicking to navigate and them clicking to say "Open this directory"?
Jon Skeet
Yes, the "leaf" menu item is the current implementation, but I don't like it much. The user shouldn't need to click to navigate; the popup menus are automatic (double clicking could be an option to minimize confusion -- if the double click event was supported).
Erlend D.
Pop up menus may be automatic in some cases, but many people like to click anyway - I know I do, as it reduces confusion from accidental hovering. It's a confirmatory step, and I certainly wouldn't want it to take an action.
Jon Skeet
A: 

If you launched your popup from a toolstrip, you can subclass the toolstrip and add this code.

  override protected void OnItemClicked(ToolStripItemClickedEventArgs e)
  {
    if (this.Items.Count == 0)
      base.OnItemClicked(e);

    // else do nothing
  }

However, the ContextMenu class does not have OnItemClicked, but it has onPopup. I have not tried it but you could try subclassing the ContextMenu

public class MyContextMenu : ContextMenu
{
  override protected void OnPopUp(EventArgs e)
  {
        if (this.MenuItems.Count == 0)
          base.OnPopUp(e);

        // else do nothing
  }
}

if that does not work then, you could override the two show methods

public class MyContextMenu : ContextMenu
{
  override protected void Show (Control c, Point p)
  {
        if (this.MenuItems.Count == 0)
          base.Show (c, p) ;

        // else do nothing
  }

  override protected void (Control c, Point p, LeftRightAlignment z) 
  {
        if (this.MenuItems.Count == 0)
          base.Show (c, p, z) ;

        // else do nothing
  }
}
Blessed Geek
I'm not sure if the logic will work, but is an illustration to subclass ContextMenu and intercept the click with your own logic withif (item count > 0) show subitemselse show shortcut
Blessed Geek