1

I have a series of CheckBox(es) in a GroupBox that select what reports a user would like to run. They are normally all Checked, the most common case, but it is is also common to want to run just one. I thought using a right-click on a box to turn it on and all the others off would be useful.

It's easy enough to implement a MouseClick event on the check boxes, but the problem is that there are a bunch of them, and the list keeps getting added to. So the first question: is there a way to have a single MouseClick handler that works for any check box, even ones we don't have yet?

The other option would seem to be to use the GroupBox.Controls collection to loop over the check boxes and see which one was clicked and then set the Checked for all of them as appropriate. However, it seems that the CheckBox always intercepts the MouseClick event, even with AutoCheck turned off. So my second question: is there a way to turn off click handling in the check boxes so that event can be handled by the group?

If there is any other way to handle this, please let me know!

Maury Markowitz
  • 9,082
  • 11
  • 46
  • 98
  • Use a single common event handler for all off them. When a new one is added, hook it up to the same handler – Ňɏssa Pøngjǣrdenlarp Apr 19 '16 at 13:37
  • Ok, less automatic than I wanted, but it works. But now I am confused how to interpret the mouse location. e(vent).location returns values relative to *that* control, so you get small numbers like 32,24. That lies within the bounds of every control, so I need to convert the coordinates, but I'm not sure how do that into a common frame of reference. – Maury Markowitz Apr 19 '16 at 13:55
  • as for your second issue, try using the mousedown event where you can check to ensure that the right button is being used, assign the sender to a variable of type checkbox, create a loop through the checkboxes setting them to false and set the variable that holds the sender to true. – Charles May Apr 19 '16 at 13:56
  • what do you mean by less automatic? This can be done with AddHandler and looping through and adding your controls at runtime. – Charles May Apr 19 '16 at 13:57
  • 1
    Why do you need location? I thought this had to do with check clicks? – Ňɏssa Pøngjǣrdenlarp Apr 19 '16 at 14:00
  • Oh yes @Plutonix, now I see what you mean. That does indeed solve it. Oh, well except that it seems it doesn't collect right-click messages! – Maury Markowitz Apr 19 '16 at 14:09
  • And here is the solution to that: http://stackoverflow.com/questions/1581627/unable-to-detect-right-mouseclick-in-combobox – Maury Markowitz Apr 19 '16 at 14:24

1 Answers1

1

Here's an example of what I'm talking about in my comments. Add a FlowLayoutPanel to a form (leaving it flowlayoutpanel1)

'This is done to show automatic generation of a list of reports.
'You might get this from a folder of reports, or a database or similar store
'By adding and taking away from this list you will notice that the code still functions the same.
'Just remember, you would dynamically fill the reports list in your real-world application.
Dim Reports As New List(Of String) From {"Report1", "Report2", "Report3", "Report4", "Report5", "Report6", "Report7", "Report8"}

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    'I'm using a flowlayoutpanel so that the controls are added
    'without having to worry about placement
    FlowLayoutPanel1.AutoScroll = True
    'Here is where we loop through the list of reports and add them to the 
    'flowlayoutpanel and give them a common handler
    For Each rpt As String In Reports
        Dim chkRpt As New CheckBox
        chkRpt.Text = rpt
        chkRpt.Height = 17
        chkRpt.Checked = True
        AddHandler chkRpt.MouseDown, AddressOf CustomMouseDown
        FlowLayoutPanel1.Controls.Add(chkRpt)
    Next
End Sub

'Here is the code to allow a right click to select the current checkbox
'and remove all other checked items.
Private Sub CustomMouseDown(sender As Object, e As MouseEventArgs)
    If e.Button = Windows.Forms.MouseButtons.Right Then
        Dim curChk As CheckBox = CType(sender, CheckBox)
        For Each chk As CheckBox In FlowLayoutPanel1.Controls.OfType(Of CheckBox)()
            chk.Checked = False
        Next
        curChk.Checked = True
    End If
End Sub
Charles May
  • 1,725
  • 1
  • 11
  • 18