我想在DataGridView的右键单击上放置一个上下文相关菜单。我希望有一个菜单项是从单击的单元格的内容派生而来的,而子菜单中有可变数量的项是从数据库中检索到的。
我通过在ContextMenuStrip Opening事件中构建ToolStripMenuItem来实现。而且有效-几乎...
如果我不显示子菜单,那么用户必须单击顶级菜单中的单个项目,一切都很好,但是如果我调用ShowDropDown方法以自动显示子菜单,则在单击项目时不会激活现有功能。
这是我可以产生的最简单的代码来重现该问题-我拔出了对DataGridView和数据库的所有引用,因此我的“动态”菜单绝对是静态的;-)
如果您输入的是表单定义,请在表单上的任意位置单击鼠标右键,然后会看到有效的行为,但不是您想要的行为-单击子菜单,然后弹出一个窗口。勾选复选框并再次右键单击,您将看到子菜单自动弹出-但是单击项目不会触发aliasClick处理程序。
有什么想法吗?在这个特定的应用程序中,我可以编写一个可以避免使用ShowDropDown的完全可行的解决方法-但是我想知道自己在做错什么,以防将来需要使用它。
public partial class Form1 : Form
{
private ContextMenuStrip cms;
private CheckBox chkAuto;
public Form1()
{
InitializeComponent();
chkAuto = new CheckBox();
Controls.Add(chkAuto);
cms = new ContextMenuStrip();
cms.Opening += contextMenuStrip1_Opening;
this.MouseClick += Form1_MouseClick;
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
cms.Show(Cursor.Position);
}
private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
{
cms.Items.Clear();
ToolStripMenuItem tsmi = new ToolStripMenuItem("Title from datagridviewcell");
tsmi.DropDownItems.Add(new ToolStripMenuItem("First item from database lookup", null, aliasClick));
tsmi.DropDownItems.Add(new ToolStripMenuItem("Second item from database lookup", null, aliasClick));
tsmi.DropDownItems.Add(new ToolStripMenuItem("Last item from database lookup", null, aliasClick));
cms.Items.Add(tsmi);
if (chkAuto.Checked)
tsmi.ShowDropDown();
e.Cancel = false;
}
private void aliasClick(object sender, EventArgs e)
{
ToolStripMenuItem clickedItem = (ToolStripMenuItem)sender;
MessageBox.Show(clickedItem.Text);
}
}
最佳答案
我不确定如何证明这一点,但是我怀疑您对tsmi.ShowDropDown()
的调用在某种程度上导致单击处理程序无法正确捕获坐标。将其替换为cms.Show(MousePosition)
即可。
也许通过查看坐标可以收集到一些有用的信息...
var mi = new ToolStripMenuItem("First item from database lookup", null, aliasClick);
tsmi.DropDownItems.Add(mi);
var mi2 = new ToolStripMenuItem("Second item from database lookup", null, aliasClick);
tsmi.DropDownItems.Add(mi2);
var mi3 = new ToolStripMenuItem("Last item from database lookup", null, aliasClick);
tsmi.DropDownItems.Add(mi3);
cms.Items.Add(tsmi);
if (chkAuto.Checked)
tsmi.ShowDropDown();
//cms.Show(MousePosition);
Debug.WriteLine(mi.Bounds.ToString());