C# 单击“离开”时仍会触发关联菜单

C# 单击“离开”时仍会触发关联菜单,c#,winforms,datagridview,contextmenu,C#,Winforms,Datagridview,Contextmenu,Winform项目 我有一个带有contextMenu的dataGridView。简单地说,一切都在按我所希望的方式工作,除了上下文菜单选择触发,即使我不希望它在我点击时触发。 例如,我右键单击我的dataGridView,我看到了我的选择。如果我选择它,它会触发一个MouseClick事件并执行我想要的操作。但是如果我点击它,它会触发鼠标点击事件 我在OnMouseUp活动中尝试了几种不同的方式,但同样的情况正在发生。你会注意到在下面的代码中有一些额外的if,基本上是我尝试了一些事情来避免鼠标

Winform项目

我有一个带有contextMenu的dataGridView。简单地说,一切都在按我所希望的方式工作,除了上下文菜单选择触发,即使我不希望它在我点击时触发。 例如,我右键单击我的dataGridView,我看到了我的选择。如果我选择它,它会触发一个MouseClick事件并执行我想要的操作。但是如果我点击它,它会触发鼠标点击事件

我在OnMouseUp活动中尝试了几种不同的方式,但同样的情况正在发生。你会注意到在下面的代码中有一些额外的if,基本上是我尝试了一些事情来避免鼠标点击触发不必要的althogh,最后我相信这只是做了一些多余的工作

在下面的代码中,请注意以下内容:MessageBox.show此处出现问题

代码:

我遗漏了什么来告诉我的应用程序在我点击时不要触发

谢谢


~Chris

发生的情况是,一旦关闭ContextMenu,您的方法将继续处理。要修复您的解决方案,您只需在为ContextMenu调用Show之后返回

简单修复:

m.Show(dgvMyDataGridView, new Point(e.X, e.Y));
return;
问题是事件处理程序的执行仍在继续,只是在上下文菜单关闭时等待m.Show结束,类似于Form.ShowDialog和MessageBox.Show的行为方式

更新:从评论中,看起来DataGridView.MouseClick试图处理用户单击上下文菜单项的情况。在这种情况下,您需要对代码进行更大的更改,如下所示:

private void dgvMyDataGridView_MouseClick(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        var hitTestInfo = dgvMyDataGridView.HitTest(e.X, e.Y);

        if ((hitTestInfo.Type == DataGridViewHitTestType.Cell) &&
            (hitTestInfo.ColumnIndex == 1) &&
            (hitTestInfo.RowIndex >= 0))
        {
            string currentCell = dgvMyDataGridView.Rows[hitTestInfo.RowIndex].Cells[hitTestInfo.ColumnIndex].Value.ToString();
            ContextMenu m = new ContextMenu();
            dgvMyDataGridView.CurrentRow.Cells[0].Value.ToString();
            m.MenuItems.Add(new MenuItem("Click Me!", new EventHandler((itemSender, itemEvent) =>
            {
                var result = MessageBox.Show("You've clicked " + currentCell + ". Open next form?", "Continue?", MessageBoxButtons.YesNo);
                if (result == System.Windows.Forms.DialogResult.Yes)
                {
                    // Code to open a new form page.
                }
            })));
            m.Show(dgvMyDataGridView, new Point(e.X, e.Y));
        }
    }
}

关键是将EventHandler添加到ContextMenu的MenuItem中。希望有帮助

不要这样创建上下文菜单,创建一个静态上下文菜单,然后设置dgvMyDataGridView.ContextMenu=m@汉斯,他希望它是静态的吗?在他的情况下,表单可能不能被多次实例化,然后单击任何表单上的菜单都会触发所有附加的处理程序,对吗?难道不仅仅是表单的一个常规成员变量就可以了吗?或者甚至为DataGridView设置ContextMenu属性,然后重新使用它?老实说,我不记得为什么要动态创建它。我相信这是因为我意识到我必须创建一个动态构建的ContextMenu我有程序员的想法,但很抱歉我没有你们这么有经验。无论如何,我是如此接近,我不想重做一切,所以我坚持下去,相信我解决了我的问题。我需要做的是通过contextMenu创建一个事件处理程序,而不是使用dgvMyDataGridView_MouseClick事件。谢谢你的意见。我相信你有什么发现。奇怪的是,它曾经工作过一次,但由于某种原因之后就没有了。我整天都在乱搞我的代码,我可能在某个时候弄坏了什么东西。我是如此接近,我不想重做每件事,所以我坚持下去,相信我解决了我的问题。我需要做的是通过contextMenu创建一个事件处理程序,而不是使用dgvMyDataGridView_MouseClick事件。对于这样的记录:m.MenuItems.Add&Do something,neweventhandlereventtocallhere;然后我设置一个事件来执行我希望它执行的操作。非常感谢您的帮助。@Chris啊,您是说您的鼠标点击处理程序的第二部分是ContextMenu的预期结果?这是一个关键点,对于以后搜索类似问题的任何人,我将更新我的答案以包含该修复。
private void dgvMyDataGridView_MouseClick(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right)
    {
        var hitTestInfo = dgvMyDataGridView.HitTest(e.X, e.Y);

        if ((hitTestInfo.Type == DataGridViewHitTestType.Cell) &&
            (hitTestInfo.ColumnIndex == 1) &&
            (hitTestInfo.RowIndex >= 0))
        {
            string currentCell = dgvMyDataGridView.Rows[hitTestInfo.RowIndex].Cells[hitTestInfo.ColumnIndex].Value.ToString();
            ContextMenu m = new ContextMenu();
            dgvMyDataGridView.CurrentRow.Cells[0].Value.ToString();
            m.MenuItems.Add(new MenuItem("Click Me!", new EventHandler((itemSender, itemEvent) =>
            {
                var result = MessageBox.Show("You've clicked " + currentCell + ". Open next form?", "Continue?", MessageBoxButtons.YesNo);
                if (result == System.Windows.Forms.DialogResult.Yes)
                {
                    // Code to open a new form page.
                }
            })));
            m.Show(dgvMyDataGridView, new Point(e.X, e.Y));
        }
    }
}