Получить событие клика по пункту меню с подпунктами (C#)

Я создаю контекстное меню, которое должно содержать список всех папок, подпапок и файлов в выбранной папке. Я хочу, чтобы меню открывало файлы и папки при нажатии на них, но событие щелчка не регистрируется, если в элементе меню есть подэлементы.

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");
}

Как сделать так, чтобы событие щелчка срабатывало, даже если в элементе меню есть подпункты?


person Erlend D.    schedule 09.08.2009    source источник


Ответы (3)


Похоже, что меню может быть не самым подходящим виджетом пользовательского интерфейса здесь. Я считаю, что причина, по которой вы не получаете событие щелчка, заключается в том, что элементы меню с подменю предполагают, что только расширяют свои дочерние элементы при нажатии, а не выполняют какое-либо другое действие.

Вероятно, это тоже предположение пользователя.

Это поведение упоминается в документации для MenuItem.Click:

Примечание. Если свойство MenuItems для MenuItem содержит какие-либо элементы, это событие не возникает. Это событие не вызывается для элементов родительского меню.

person Jon Skeet    schedule 09.08.2009
comment
Предполагается, что это крошечное приложение, которое очень легко дает доступ к наиболее часто используемым папкам, файлам, веб-сайтам и т. д. Моя идея - это значок в трее с контекстным меню, так как я не вижу никаких других элементов управления, которые были бы легко доступны и скрыты, когда они не используются. Значит, нельзя поднять событие? - person Erlend D.; 09.08.2009
comment
Подозреваю, что не без гротескного хака. Однако вы можете добавить элемент листового меню в каждый каталог с именем [Этот каталог]. Как бы вы определили разницу между щелчком пользователя для перехода и нажатием кнопки «Открыть этот каталог»? - person Jon Skeet; 09.08.2009
comment
Да, пункт меню листа — это текущая реализация, но мне она не очень нравится. Пользователю не нужно нажимать для навигации; всплывающие меню автоматические (двойной щелчок может быть вариантом для минимизации путаницы - если поддерживается событие двойного щелчка). - person Erlend D.; 09.08.2009
comment
Всплывающие меню могут быть автоматическими в некоторых случаях, но многие люди все равно любят нажимать на них — я знаю, что да, так как это уменьшает путаницу из-за случайного наведения. Это подтверждающий шаг, и я определенно не хотел бы, чтобы он предпринимал какие-либо действия. - person Jon Skeet; 09.08.2009

Если вы запустили свое всплывающее окно из панели инструментов, вы можете создать подкласс панели инструментов и добавить этот код.

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

    // else do nothing
  }

Однако класс ContextMenu не имеет OnItemClicked, но имеет onPopup. Я не пробовал, но вы можете попробовать создать подкласс ContextMenu

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

        // else do nothing
  }
}

если это не сработает, вы можете переопределить два метода show

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
  }
}
person Blessed Geek    schedule 10.08.2009
comment
Я не уверен, что логика будет работать, но это иллюстрация к подклассу ContextMenu и перехватывает щелчок с помощью вашей собственной логики, если (количество элементов › 0) показать подэлементы, иначе показать ярлык - person Blessed Geek; 10.08.2009

У меня была такая же проблема, решение состояло в том, чтобы использовать MenuItem.SubmenuOpened" вместо события клика.

person Qjimbo    schedule 20.11.2018