Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: VB.NET
Basically what I have is a Datagridview that I want to show a context menu strip when it is right clicked. But only when right clicked on a cell, not on the header or a blank part of the datagridview control. I also want it to select the entire row when right clicked. I have the row selection working, and the context menu strip opens but it open way away from the mouse as per the screenshot.
 
    Private Sub DgvDelays_CellMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles DgvDelays.CellMouseDown
        Dim rowClicked As DataGridView.HitTestInfo = DgvDelays.HitTest(e.X, e.Y)
        'Select Right Clicked Row if its not the header row
        If e.Button = Windows.Forms.MouseButtons.Right AndAlso e.RowIndex > -1 Then
            'Clear any currently sellected rows
            DgvDelays.ClearSelection()
            Me.DgvDelays.Rows(e.RowIndex).Selected = True
            CmsRightClick.Show(DgvDelays, New System.Drawing.Point(Windows.Forms.Cursor.Position))
 
        End If
 
    End Sub
 
Image[^]
Posted 30-Dec-12 18:31pm
brzt409
Comments
Sergey Alexandrovich Kryukov at 31-Dec-12 0:57am
   
System.Windows.Forms? Tag it!
—SA
Sergey Alexandrovich Kryukov at 31-Dec-12 1:00am
   
So, is the location of context menu string the only problem? What is the line of code showing it? CmsRightClick.Show?
—SA
brzt at 31-Dec-12 1:06am
   
Yes just the location that its loading at, I have included all my code for the sub as I was thinking it might be part of the problem.
 
CmsRightClick.Show(DgvDelays, New System.Drawing.Point(Windows.Forms.Cursor.Position))
 
^^Code That Shows The Menu^^
Sergey Alexandrovich Kryukov at 31-Dec-12 1:21am
   
OK, that's what I thought. Then I have a solution for you; please see Solution 1.
Hope it works for you, so you could formally accept it (green button).
—SA
brzt at 31-Dec-12 2:57am
   
Thanks Mate,
Heading out for NYE Celebrations. Will Check and confirm it as working tomorrow and accept the solution if it is. Thank you :D
Sergey Alexandrovich Kryukov at 31-Dec-12 11:50am
   
Sure. Happy New Year!
—SA
brzt at 1-Jan-13 0:17am
   
Hey SA,
I'm having issues getting your solution to work. Maybe some more information will help you.
 
CmsRightClick.Show(DgvDelays, New System.Drawing.Point(Windows.Forms.Cursor.Position))
 
Cmsrightclick <- Context menu stripe called CmsRightClick
DgvDelays <- Data Grid View Control called DgvDelays
Sergey Alexandrovich Kryukov at 1-Jan-13 0:21am
   
What's the problem? Look at the parameters of the function: one of them is e As System.Windows.Forms.DataGridViewCellMouseEventArgs.
 
Try:
 
CmsRightClick.Show(DgvDelays, New System.Drawing.Point(e.X, e.Y))
 
—SA
brzt at 1-Jan-13 0:33am
   
That is what I tried but The menu opens up way off.
http://img23.imageshack.us/img23/9955/help2p.jpg
Sergey Alexandrovich Kryukov at 1-Jan-13 1:41am
   
Are you sure it's the same?
Isn't the shift equals to the location of the control in screen coordinates? Will you check up?
—SA
Sergey Alexandrovich Kryukov at 1-Jan-13 1:45am
   
You must make some mistake. Didn't you do something else, like CmsRightClick.Show(e.X,e.Y)? This is not the same.
 
Show with too integer parameters shows in screen coordinates.
—SA
brzt at 1-Jan-13 1:53am
   
Private Sub DgvDelays_CellMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles DgvDelays.CellMouseDown
Dim rowClicked As DataGridView.HitTestInfo = DgvDelays.HitTest(e.X, e.Y)
 

'Select Right Clicked Row if its not the header row
If e.Button = Windows.Forms.MouseButtons.Right AndAlso e.RowIndex > -1 Then
'Clear any currently sellected rows
DgvDelays.ClearSelection()
Me.DgvDelays.Rows(e.RowIndex).Selected = True
CmsRightClick.Show(DgvDelays, New System.Drawing.Point(e.X, e.Y))
'CmsRightClick.Show(DgvDelays, New System.Drawing.Point(Windows.Forms.Cursor.Position))
End If
 

End Sub
Sergey Alexandrovich Kryukov at 1-Jan-13 1:58am
   
Hm... looks correct...
Are you sure next line was really commented out? :-)
Please see, I updated the answer with the variants of resolution... other Show methods should work with Windows.Forms.Cursor.Position.
—SA
brzt at 1-Jan-13 2:03am
   
100% Sure its commented out. 
I'm not sure why it’s not working either. I'm going to try compiling it and running it on another computer see it maybe its linked to my local machine. It’s a long shot but I’m not sure what else to try.
Sergey Alexandrovich Kryukov at 1-Jan-13 2:06am
   
I don't think it'll work. Try a different method. After [EDIT], I listed 4. It's just... needs some attention and work/debugging. I vaguely remember I had to spend some time when I wanted to show a context menu in proper location. Maybe e.X and e.Y are not what we expect. You can always verify coordinates under the debugger.
—SA
brzt at 1-Jan-13 2:16am
   
Okay, I think I have figured out what is going on, the e.x and e.y positions being returned are relevant to the cell. Meaning the the Top Left of any Cell is 0,0.
The Question still remains how to fix this. If I run it code only on mouse down of the control it doesn't only show the context menu when you right click on a cell it show it when you right click any where in the control.
Sergey Alexandrovich Kryukov at 1-Jan-13 2:20am
   
Right, good! But what's the problem? Then use one of two remaining solutions, with Cursor.Position. Use it with one of the two other Show methods. (Or find out cell coordinate and add it.)
—SA
brzt at 1-Jan-13 2:33am
   
I think I have found an easier solution
brzt at 1-Jan-13 2:34am
   
Thank you so much for all your help, this has been doing my head in for the last few days.
Sergey Alexandrovich Kryukov at 1-Jan-13 2:39am
   
And I think you ought to accept my solution formally (green button), as it is correct (I'll only fix one statement) — thanks.
—SA
brzt at 1-Jan-13 2:44am
   
Happy To Select Both As Correct.
Sergey Alexandrovich Kryukov at 1-Jan-13 3:37am
   
Thanks.
Good luck, call again.
-SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Please see my comments to the question — I'm not 100% sure I understand your code, because incomplete code is shown. If some of my assumptions are wrong, we can sort things out if you clarify it.
 
It looks like you obtain cursor position in screen coordinates; and the menu is created in control coordinates. You need to add appropriate shift. One of the ways to do it is the pair of methods: System.Windows.Forms.Control.PointToClient and System.Windows.Forms.Control.PointToScreen. Please see:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.pointtoclient.aspx[^],
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.pointtoscreen.aspx[^].
 
Another approach: don't use Windows.Forms.Cursor.Position. Obtain mouse coordinates in control's coordinate system in first place, by handling the event MouseUp of this control.
 
[EDIT]
 
Don't mix up different Show methods.
 
These two show in screen coordinates:
http://msdn.microsoft.com/en-us/library/xz0wbhy2.aspx[^],
http://msdn.microsoft.com/en-us/library/7z41k67k.aspx[^].
 
These two show relative to the control passes as first parameter:
http://msdn.microsoft.com/en-us/library/71tzk45y.aspx[^],
http://msdn.microsoft.com/en-us/library/15e8969w.aspx[^].
 
In first case, you can use Windows.Forms.Cursor.Position, in second case — coordinates passed in the parameter e. Use some extra attention; it's easy to make a mistake.
 
Good luck,
—SA
  Permalink  
v3
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

Ok I Have Found A Solution, using to publicly shared Variables, then storing the location the mouse is clicked when it is clicked any where on the control but only running the show context menu when the mouse down is on a cell.
 
Very Big Thank you to Sergey Alexandrovich Kryukov, for working through this with me
 

    
Public Shared MouseX As Integer
Public Shared MouseY As Integer
 
Then Use The Following Code For The Mouse Down On The Cell
 
    Private Sub DgvDelays_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DgvDelays.MouseDown
        MouseX = e.X
        MouseY = e.Y
    End Sub
 
And the Following Code In The Cell Mouse Down
 
    Private Sub DgvDelays_CellMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles DgvDelays.CellMouseDown
        Dim rowClicked As DataGridView.HitTestInfo = DgvDelays.HitTest(e.X, e.Y)
 
        'Select Right Clicked Row if its not the header row
        If e.Button = Windows.Forms.MouseButtons.Right AndAlso e.RowIndex > -1 Then
            'Clear any currently sellected rows
            DgvDelays.ClearSelection()
            Me.DgvDelays.Rows(e.RowIndex).Selected = True
            CmsRightClick.Show(DgvDelays, New System.Drawing.Point(MouseX, MouseY))
        End If
 

    End Sub
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 693
1 George Jonsson 370
2 BillWoodruff 337
3 Sergey Alexandrovich Kryukov 259
4 Garth J Lancaster 240
0 Sergey Alexandrovich Kryukov 10,764
1 Maciej Los 5,474
2 OriginalGriff 5,472
3 CPallini 3,819
4 BillWoodruff 3,594


Advertise | Privacy | Mobile
Web03 | 2.8.141030.1 | Last Updated 1 Jan 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100