Прихващане на събитие за щракване за програмно генерирано подменю на контекстно меню

Опитвам се да хвана събитие за щракване върху подменю на контекстно меню, създадено динамично от следния код. Контекстното меню 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;
}

Как мога да създам код, който да се изпълни, когато се щракне върху подменюто на който и да е от елементите на контекстното меню и да има налична идентичност на елемента от подменюто (зададена в свойството text)?

Опитах се да добавя манипулатор на събития с помощта на

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

където създавам функцията

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

Тази функция се извиква, когато се щракне върху подменюто, но нито sender, нито e имат информация за щракнатия елемент от подменюто - sender е 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(); 
} ));

Тъй като анонимният метод е деклариран in place, той има достъп до локалната променлива i. Така че по този начин не е необходимо да използвате подател.

Редактиране: Оказва се, че i се променя в for цикъла. Така че трябва да използвам индекс на локално копие, за да запазя стойността му.

А що се отнася до втория ви въпрос,

Получавам несъответствие на типа време на компилиране за последния параметър на DropDownItems.Add.

Това е така, защото подписът на InfoClicked не съвпада с подписа на делегата ToolStripItemClickedEventHandler.

person kennyzx    schedule 30.10.2018
comment
Това е страхотно - работи добре. Замених MessageBox.Show с код за показване на помощ в зависимост от това върху кое подменю е щракнато. Много благодаря. - person SimonKravis; 30.10.2018