【问题标题】:Context menu not displaying near datagridview cell where right click occurred右键单击发生的 datagridview 单元格附近未显示上下文菜单
【发布时间】:2018-01-11 14:07:42
【问题描述】:

我在弹出上下文菜单时遇到了一些问题。 我有一个datagridview,我希望用户能够右键单击一个单元格并显示上下文菜单。用户可以多选连续或非连续单元格。右键单击并获取上下文菜单。我已经阅读了堆栈溢出问题并尝试了这些建议,但没有一个对我有用。上下文菜单不会显示在所选单元格附近。

我在 datagridview cellmouse down 事件后面编码并检查鼠标右键。这是我的代码:

if (e.Button == MouseButtons.Right)
{
    ContextMenu m = new ContextMenu();
    MenuItem mi = new MenuItem("Set Online");
    mi.Click += setOnlineItemCell_Click;
    m.MenuItems.Add(mi);

    MenuItem mi2 = new MenuItem("Set Offline");
    mi2.Click += setOfflineItemCell_Click;
    m.MenuItems.Add(mi2);

    m.Show(machineGrid, new Point(e.X, e.Y));
}

我不能只向 Show 方法传递一个参数,因为它抱怨找不到它(即使 MSDN 说你可以)。

非常感谢任何帮助让上下文菜单显示在单元格附近。

C#、Visual Studio 2015 专业版、.NET 4.5.2

【问题讨论】:

    标签: c# datagridview contextmenu


    【解决方案1】:

    让上下文菜单显示在最后一个“选定”单元格旁边是可行的;但是,它不会对用户非常友好。在大多数情况下,当用户“右键单击”某物时,上下文菜单预计会出现在用户“右键单击”时鼠标“指针”所在的“下方”。您所描述的是将上下文菜单从鼠标“箭头”所在的位置“移开”。我相信大多数用户不会期待这一点。

    我从您发布的内容中猜测...用户选择了网格中的多个单元格,然后用户“右键单击”网格上的某个位置。这将显示一个上下文菜单(在鼠标下方,而不是将菜单移动到某个选定的单元格)。上下文菜单将显示“离线/在线”菜单项。然后在用户选择“在线/离线”后,一些方法会使用网格中“选中”的单元格作为数据来设置单元格在线或离线。这大约是我从你的问题中可以破译的。

    为了提供帮助,以下是一些建议。帖子最后一行代码……

    m.Show(machineGrid, new Point(e.X, e.Y));
    

    以上行使用 UI 坐标将上下文菜单移动到网格 X、Y 值。这似乎与“选择”哪些单元格无关。然而,这会将上下文菜单移动到用户右键单击的位置上方……迫使用户“追逐”上下文菜单。

    最后,我质疑使用“CellMouseDown”事件来执行此上下文菜单逻辑。 DataGridView 有自己的“ContextMenuStrip”,您可以设置它。使用 DataGridView’s ContextMenuStrip 可能是一种更简单的方法。下面是一个将名为 dgv_PlayerPoolDataGridView 设置为 ContextMenuStrip 的示例。

    private void SetContexMenu() {
      ContextMenuStrip cms = new ContextMenuStrip();
      cms.Items.Add("Set OnLine", null, setOnline_Click);
      cms.Items.Add("Set OffLine", null, setOffline_Click);
      dgv_PlayerPool.ContextMenuStrip = cms;
    }
    

    上面的项目添加行,在菜单中显示一个字符串,一个图像,最后是一个点击时调用的事件。

    当用户选择上下文菜单项时触发的事件。

    private void setOffline_Click(object sender, EventArgs e) {
      MessageBox.Show("SetOffLine");
    }
    private void setOnline_Click(object sender, EventArgs e) {
      MessageBox.Show("SetOnLine");
    }
    

    希望这是有道理的。

    【讨论】:

    • 感谢您帮助我解决问题。我不知道我为什么这么白痴。
    • 很高兴为您提供帮助。加入人群;有一天实现一个想法,然后检查相同的代码并对自己说……“我在想什么!”去过也做过! :-) 祝你好运!
    猜你喜欢
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 2019-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多