user2065612
user2065612

Reputation: 471

Why when clicking mouse right button on listBox it's working everywhere in the listBox area?

I have this two events in 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));                
            }
        }

In the designer I have a ContextMenuStrip and a listBox controls.

What I need it to do is when I click on the mouse right button anywhere on the listBox area it will not do anything. But If I click only on the selected item in the listBox then the contextMenuStrip will show. Only if the mouse above/on the selected item in the listBox.

When my program is running already the first item is selected so I need that once I run my program if I move my mouse above the selected item and make right click button it will work. If i'm not on the selected item it will not work. I mean only if the mouse cursor is above the selected item then right click will work and show the contextmenustrip.

Not ifi move the mouse over the selected item if I put the mouse over the selected item now if I click the right mouse button it will work.

Upvotes: 0

Views: 1374

Answers (1)

Hans Passant
Hans Passant

Reputation: 941417

ListBox.IndexFromPoint() is pretty liberal in what it accepts. A location that's beyond the last item in the list will return the index of the last item. You can fix that by double-checking the position of the returned item against the mouse position, like this:

    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);
            }
        }
    }

Do note that I didn't follow your request to force the user to only click the selected item. Pretty unreasonable to throw away a user action like that, it is much more intuitive to simply select the clicked item. If you don't want to do this then change the GetItemRectangle() call to use listBox1.SelectedIndex instead of idx. Just make sure that you don't get into trouble when there is no selected item yet.

Upvotes: 2

Related Questions