为什么在listBox上单击鼠标右键时它在listBox区域的任何地方都可以使用?

时间:2013-02-17 13:15:52

标签: c#

我在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将显示。仅当鼠标位于列表框中所选项目的上方/上方时。

当我的程序运行时,已经选择了第一个项目,所以如果我将鼠标移动到所选项目之上并按下右键单击按钮就可以运行我的程序。如果我不在所选项目上,它将无法工作。我的意思是只有当鼠标光标位于所选项目的上方时,才会右键单击并显示contextmenustrip。

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

1 个答案:

答案 0 :(得分: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 。确保在没有选定项目时不会遇到麻烦。