0

我在 Form1 中有这两个事件:

private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {
            //clear the menu and add custom items
            contextMenuStrip1.Items.Clear();
            contextMenuStrip1.Items.Add(string.Format("Edit - {0}", listBox1.SelectedItem.ToString()));
        }

        private void listBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                int index = listBox1.IndexFromPoint(e.Location);
                if (index == -1) return;
                contextMenuStrip1.Show(listBox1,listBox1.PointToClient(System.Windows.Forms.Cursor.Position));                
            }
        }

在设计器中,我有一个 ContextMenuStrip 和一个 listBox 控件。

我需要它做的是,当我在 listBox 区域的任意位置单击鼠标右键时,它不会执行任何操作。但是,如果我只单击 listBox 中的选定项目,则会显示 contextMenuStrip。仅当鼠标在列表框中的选定项目上方/上时。

当我的程序正在运行时,第一个项目已被选中,因此我需要在运行程序后将鼠标移到所选项目上方并右键单击按钮,它将起作用。如果我不在所选项目上,它将不起作用。我的意思是只有当鼠标光标位于所选项目上方时,右键单击才会起作用并显示上下文菜单条。

如果我现在将鼠标放在所选项目上,如果我单击鼠标右键,则不会将鼠标移到所选项目上,它会起作用。

4

1 回答 1

1

ListBox.IndexFromPoint() 接受的内容非常自由。超出列表中最后一项的位置将返回最后一项的索引。您可以通过根据鼠标位置仔细检查返回项目的位置来解决此问题,如下所示:

    private void listBox1_MouseDown(object sender, MouseEventArgs e) {
        if (e.Button == MouseButtons.Right) {
            var idx = listBox1.IndexFromPoint(e.Location);
            if (idx >= 0 && listBox1.GetItemRectangle(idx).Contains(e.Location)) {
                listBox1.SelectedIndex = idx;
                contextMenuStrip1.Show(listBox1, e.Location);
            }
        }
    }

请注意,我没有按照您的要求强制用户仅单击所选项目。放弃这样的用户操作是非常不合理的,简单地选择单击的项目要直观得多。如果您不想这样做,请更改 GetItemRectangle() 调用以使用 listBox1.SelectedIndex 而不是idx。只要确保在还没有选定项目时不会遇到麻烦。

于 2013-02-17T13:32:00.127 回答