6

I have a ComboBox that is a simple drop down style. I wanted to open a new window when the user right clicks on an item in the list, but am having trouble getting it to detect a right click has occurred.

My code:

private void cmbCardList_MouseClick(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Right && cmbCardList.SelectedIndex != -1)
    {
        frmViewCard vc = new frmViewCard();
        vc.updateCardDisplay(cmbCardList.SelectedItem);
        vc.Show();
    }
}

If I change e.Button == MouseButtons.Left the whole thing fires off just fine. Any way I can get this working as I intend?

o.k.w
  • 25,490
  • 6
  • 66
  • 63
marco0009
  • 163
  • 2
  • 8
  • 3
    In my opinion, right-clicks on buttons/combos etc are counter-inituitive. You might want to use another method to perform what you want. Make it more usable and easier to implement too. – o.k.w Oct 17 '09 at 07:21
  • The app I'm making is a utility to work with data files that are no longer maintained, but utilized by another piece of software (that I didn't make). The behavior I'm seeking is simply emulating a similar behavior in this other program, so it shouldn't be so foreign to anyone who uses my app. There is an alternate method to procure the dialog I want to display, but I'm more interested right now in making the little shortcuts available in the original app available in mine. – marco0009 Oct 17 '09 at 08:54

3 Answers3

9

I'm afraid that will not be posible unless you do some serious hacking. This article will explain.

Quoted for you:

Individual Controls

The following controls do not conform to the standard mouse click event behavior:

Button, CheckBox, ComboBox, and RadioButton controls

  • Left click: Click, MouseClick

  • Right click: No click events raised

  • Left double-click: Click, MouseClick; Click, MouseClick

  • Right double-click: No click events raised

o.k.w
  • 25,490
  • 6
  • 66
  • 63
6

As an epitaph to this question, you can make this work using normal .NET functionality; you just have to go a little deeper into the event call stack. Instead of handling the MouseClick event, handle the MouseDown event. I had to do something similar recently, and I simply overrode the OnMouseDown method instead of attaching a handler. But, a handler should work too. Here's the code:

    protected override void OnMouseDown(MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right && !HandlingRightClick)
        {
            HandlingRightClick = true;
            if (!cmsRightClickMenu.Visible)
                cmsRightClickMenu.Show(this, e.Location);
            else cmsRightClickMenu.Hide();
        }
        base.OnMouseDown(e);
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        HandlingRightClick = false;
        base.OnMouseUp(e);
    }

    private bool HandlingRightClick { get; set; }

The HandlingRightClick property is to prevent multiple triggers of the OnMouseDown logic; the UI will send multiple MouseDown messages, which can interfere with hiding the right-click menu. To prevent this, I only perform the logic once on the first MouseDown trigger (the logic's simple enough that I don't care if two invocations happen to race, but you might), then ignore any other MouseDown triggers until a MouseUp occurs. It's not perfect, but this'll do what you need it to.

KeithS
  • 70,210
  • 21
  • 112
  • 164
0

You can use the Opening event of ContextMenuStrip to handle right click event.

var chk = new CheckBox();
chk.ContextMenuStrip = cmsNone;

private void cmsNone_Opening(object sender, CancelEventArgs e)
{
    e.Cancel = true;
    var cms = (ContextMenuStrip)sender;
    var chk = cms.SourceControl;
    //do your stuff
}
IlPADlI
  • 1,943
  • 18
  • 22