ColumnHeaderMouseClick and ContextMenuStrip on DataGridView

pettrer

Well-known member
Joined
Sep 5, 2008
Messages
92
Programming Experience
10+
Hi,

I have a question regarding ColumnHeaderMouseClick, ContextMenuStrip, and DataGridViews (pew - those descriptive but LONG names!;)).

I want to set a contextmenustrip on my datagridviews' column header cells/column header rows. I inherit my forms from a parent form and there I also set some settings for each datagridview, as pictured below (it works great so feel free to use it in your own projects).


VB.NET:
Private Sub Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim kontrollen As Control = Me.GetNextControl(Me, True)
        Do Until kontrollen Is Nothing
            If TypeOf kontrollen Is DataGridView Then
                dgvSettings(kontrollen)
            ElseIf TypeOf kontrollen Is Button Then
              '...
            End If
            kontrollen = Me.GetNextControl(kontrollen, True)
        Loop
    End Sub

    Private Sub dgvSettings(ByRef DGV As DataGridView)
        DGV.AllowUserToResizeColumns = True
        DGV.AllowUserToResizeRows = False
        '...
    End Sub

Now, in this DGVSettings sub I want to set a contextmenustrip (such as DGV.onColumnHeaderMouseClick = SubRightClick() and in that new sub check for right clicks and if appropriate show the contextmenustrip). However, I can't figure out how to write this. Any ideas?

Best wishes for the new year!:)
/Pettrer
 
You simply handle the ColumnHeaderMouseClick event, test the e.Button property and call Show on a ContextMenuStrip.

Hi,

Hope the holidays have been fine. Thanks for replying to my question. However, I don't know how to set a generic sub to catch the ColumnHeaderMouseClick event. If I only were to create a sub for the specific event for a datagridview in particular, then I'd understand (i.e. click the flash button in the properties window or find the event in the drop down menu in code view). There must be some kind of coding procedure that I haven't seen before. Could you please just write the line to catch the event (and put it wherever it should be in the code snippet I previously showed)?

Thanks a lot in advance!

Pettrer
 
What you said is exactly what you do. ColumnHeaderMouseClick is an event of the grid itself, not of the column. If it was an event of the column then it would just be called HeaderMouseClick.
 
What you said is exactly what you do. ColumnHeaderMouseClick is an event of the grid itself, not of the column. If it was an event of the column then it would just be called HeaderMouseClick.

Hi again,

Thanks for your reply. If I understand you correctly there is no way of setting this on a global basis, but at the same time I don't think that is what you are explicitly telling me. If I've been unclear before, here's another effort to explain what I'm trying to achieve:

I "initalise" the apperance and behaviour of all my datagridviews (a few hundred) from the sub dgvSettings in the form that all other forms are inherited from. Everything works fine (such as setting the colour of the currently selected row). What I'm trying to add is a way of firing an event that pops up a context menu when a column header is right-clicked. What I cannot figure out is how to catch this event in the sub dgvSettings (or how to accomplish this task otherwise, on a global basis).

Warm regards from a snowy Stockholm,
Pettrer
 
You can use AddHandler statement to add event handlers dynamically, I'm not sure if you need to, but if you need more info you need to give more info about you setup.
 
Hi again,

This is what I wrote now:

VB.NET:
...(DgvSettings)           
        AddHandler DGV.ColumnHeaderMouseClick, AddressOf LaddacmRubrikrad
    End Sub

    Private Sub LaddacmRubrikrad()
        cmRubrikrad.Show()
    End Sub

This solution causes two problems.
1. The contextmenustrip is positioned in the upper left corner of the window. I tried cmRubrikrad.Show(PointToScreen(MousePosition)) but that offset the contextmenustrip more or less arbitrary.
2. In the sub I call when I click a menu item (now that they finally DO appear onscreen! - THANKS! ), there is no source control:

VB.NET:
Private Sub KopieraAlltToolStripMenuItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles KopieraAlltToolStripMenuItem.Click
        Dim dgv As DataGridView = cmRubrikrad.SourceControl
so I get a Nothing (null exception) error. Am I approaching this the wrong way? I really don't want to to manually set each datagridview header's contextmenustrip but am not sure if these obstacles can be overcome.

Thanks!
Pettrer
 
When a context menu is not attached to ContextMenuStrip property of a control, there is either no SourceControl, or it is the control you specify as parameter to the Show call. A column header is not a control, so the closest you get here is passing on the Datagridview control as specified by sender parameter of ColumnHeaderMouseClick event. Here you can also get more information about what column was clicked from the e event data, this info you can store where you want, for example in Tag property of the context menu strip.
Use the given datagridview (sender) and its PointToClient method with Cursor.Position to get the best Point to place the ct-menu.
 
Hi John,

Thanks for trying to help me out.

I gave up on creating a cntextmenustrip on only the headerrow. BUT I was able to do it easily on the entire datagridview, so that's how I ended up! This is how (in dgvSettings)

VB.NET:
        DGV.ContextMenuStrip = cmRubrikrad

(Some cells have other contextmenustrips that override this default one, and that works just fine.)

Thanks again,

Pettrer
 
I gave up on creating a cntextmenustrip on only the headerrow.
It can be done as I descibed in previous post, but if you just want to set ContextMenuStrip property and you want different menu for different columns you can see each DataGridViewColumn in dgv.Columns collection also has an independent ContextMenuStrip property.
 
Thanks, Maybe I'l redo it the way you described to me some day whe I feel more comfortable with everything!

Pettrer
 
Back
Top