Перехват события щелчка для программно сгенерированного подменю контекстного меню

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

for (int i = 0; i <= sTagsContext.GetUpperBound(0); i++)
{
    cmListTags.Items.Add(sTagsContext[i]);
    ToolStripMenuItem submenu = new ToolStripMenuItem();                  
    submenu.Text = i.ToString();
    submenu.Image = Properties.Resources.InfoBig;

    (cmListTags.Items[i] as ToolStripMenuItem).DropDownItems.Add(submenu);                    
     chkListTags.ContextMenuStrip = cmListTags;
}

Как я могу создать код, который будет выполняться при щелчке подменю любого из элементов контекстного меню и иметь доступную идентификацию элемента подменю (установленную в текстовом свойстве)?

Я попытался добавить обработчик событий, используя

(cmListTags.Items[i] as ToolStripMenuItem).DropDownItems.Add(i.ToString(), Properties.Resources.InfoBig, new EventHandler(InfoClicked));

где я создаю функцию

public void InfoClicked(object sender, EventArgs e)
{
}

Эта функция вызывается при щелчке подменю, но ни отправитель, ни e не имеют никакой информации о нажатом элементе подменю - отправитель имеет значение null, а e пуст.

Если я установлю e для типа ToolStripItemClickedEventArgs и изменю строку добавления раскрывающегося списка на

(cmListTags.Items[i] as ToolStripMenuItem).DropDownItems.Add(i.ToString(), Properties.Resources.InfoBig, new ToolStripItemClickedEventHandler(InfoClicked));

Я получаю несоответствие типа времени компиляции для последнего параметра DropDownItems.Add.


person SimonKravis    schedule 30.10.2018    source источник
comment
Я отредактировал ваш код и удалил лишнюю строку, пожалуйста, проверьте.   -  person kennyzx    schedule 30.10.2018


Ответы (1)


Вы можете использовать анонимный метод - тело метода без имени.

int index = i;
cmListTags.Items[i] as ToolStripMenuItem).DropDownItems.Add(
     i.ToString(), 
     Properties.Resources.InfoBig, 
     (s, args) => {
         MessageBox.Show(index.ToString(); 
} ));

Поскольку анонимный метод объявлен на месте, он имеет доступ к локальной переменной i. Таким образом, вам не нужно использовать sender.

Изменить: оказывается, i изменяется в цикле for. Поэтому я должен использовать локальную копию index, чтобы сохранить его значение.

А что касается вашего 2-го вопроса,

Я получаю несоответствие типа времени компиляции для последнего параметра DropDownItems.Add.

Это связано с тем, что подпись InfoClicked не соответствует подписи делегата ToolStripItemClickedEventHandler.

person kennyzx    schedule 30.10.2018
comment
Это здорово - отлично работает. Я заменил MessageBox.Show кодом, чтобы показать справку в зависимости от того, какое подменю было нажато. Большое спасибо. - person SimonKravis; 30.10.2018