Eu tenho um ContextMenuStrip
que está atribuído a várias caixas de listagem diferentes. Estou tentando descobrir quando o ContextMenuStrip
é clicado em que ListBox
foi usado. Tentei o código abaixo para começar, mas não está funcionando. O sender
tem o valor correto, mas quando tento atribuí-lo ao, menuSubmitted
ele é nulo.
private void MenuViewDetails_Click(object sender, EventArgs e)
{
ContextMenu menuSubmitted = sender as ContextMenu;
if (menuSubmitted != null)
{
Control sourceControl = menuSubmitted.SourceControl;
}
}
Qualquer ajuda seria ótimo. Obrigado.
Usando a ajuda abaixo, descobri:
private void MenuViewDetails_Click(object sender, EventArgs e)
{
ToolStripMenuItem menuItem = sender as ToolStripMenuItem;
if (menuItem != null)
{
ContextMenuStrip calendarMenu = menuItem.Owner as ContextMenuStrip;
if (calendarMenu != null)
{
Control controlSelected = calendarMenu.SourceControl;
}
}
}
c#
.net
winforms
contextmenustrip
Taryn
fonte
fonte
if
instruções e usarif (menuItem == null) return;
se você for como eu e não quiser que seu código que lida com isso seja aninhado em 2 níveis desnecessários extras.Respostas:
Para um
ContextMenu
:O problema é que o
sender
parâmetro aponta para o item no menu de contexto que foi clicado, não para o menu de contexto em si.É uma correção simples, porém, porque cada
MenuItem
um expõe umGetContextMenu
método que dirá qualContextMenu
contém aquele item de menu.Altere seu código para o seguinte:
private void MenuViewDetails_Click(object sender, EventArgs e) { // Try to cast the sender to a MenuItem MenuItem menuItem = sender as MenuItem; if (menuItem != null) { // Retrieve the ContextMenu that contains this MenuItem ContextMenu menu = menuItem.GetContextMenu(); // Get the control that is displaying this context menu Control sourceControl = menu.SourceControl; } }
Para um
ContextMenuStrip
:Isso muda um pouco as coisas se você usar um em
ContextMenuStrip
vez de aContextMenu
. Os dois controles não estão relacionados um ao outro e uma instância de um não pode ser convertida em uma instância do outro.Como antes, o item que foi clicado ainda é retornado no
sender
parâmetro, então você terá que determinar oContextMenuStrip
que possui este item de menu individual. Você faz isso com aOwner
propriedade . Finalmente, você usará aSourceControl
propriedade para determinar qual controle está exibindo o menu de contexto.Modifique seu código da seguinte maneira:
private void MenuViewDetails_Click(object sender, EventArgs e) { // Try to cast the sender to a ToolStripItem ToolStripItem menuItem = sender as ToolStripItem; if (menuItem != null) { // Retrieve the ContextMenuStrip that owns this ToolStripItem ContextMenuStrip owner = menuItem.Owner as ContextMenuStrip; if (owner != null) { // Get the control that is displaying this context menu Control sourceControl = owner.SourceControl; } } }
fonte
ContextMenu
eContextMenuStrip
. (Ah, e vejo que você já descobriu. Bem, melhor ainda para aprender as coisas por conta própria!)SourceControl
infelizmente é nulo no momento em que umClick
evento de umToolStripItem
subitem deContextMenuStrip
é disparado. Parece que oContextMenuStrip
'sClosed
evento é acionado antes queClick
evento, que é provavelmente o que causa o problema; Presumo que a propriedade seja limpa depois que o menu 'fecha'.OwnerItem
propriedades até encontrar umToolStripItem
que tenha umContextMenuStrip
em suaOwner
propriedade. Mas, como acabei de comentar, não funciona; oSourceControl
no menu de contexto será nulo. Você disse que não pode reproduzi-lo ... talvez o problema só ocorra com menus mais profundos do que um nível? O meu tinha dois níveis de profundidade.Postagem mais antiga, mas no caso de alguém como eu descobrir:
Para um ContextMenuStrip, o acima não funcionou para mim, mas levou a encontrar o que funcionou.
void DeleteMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { ContextMenuStrip menu = sender as ContextMenuStrip; Control sourceControl = menu.SourceControl; MessageBox.Show(sourceControl.Name); }
Isso me deu o nome do controle esperado. Você pode colocar validação, etc, com instruções if, estou apenas postando para ir direto ao ponto.
fonte
ContextMenu
. O problema é queItemClicked
não dispara ao clicar nos itens do submenu ; eles precisam de seu próprioClick
evento, que teria o item em si como remetente, não o menu.Tive grande dificuldade em fazer esse código funcionar. Esta é a solução mais simples que encontrei:
Para um ContextMenuStrip:
Control _sourceControl = null; private void contextMenuStrip_Opened(object sender, EventArgs e) { _sourceControl = contextMenuStrip.SourceControl; } private void contextMenuItem_Click(object sender, EventArgs e) { var menuItem = (ToolStripMenuItem)sender; _sourceControl.Text = menuItem.Text; MessageBox.Show(menuItem.Name); MessageBox.Show(sourceControl.Name); }
fonte
A solução mais fácil seria:
Control parentControl = ((sender as MenuItem).GetContextMenu()).SourceControl;
fonte