Éric Moreau
asked on
Detect which part of a CheckBox control was clicked
For a CheckBox control in .Net (WinForms) , is there a way to detect if the user really clicked within the boundaries of the square of the checkbox?
Currently, the Checked state gets changed even if the text label is clicked.
FYI, I cannot remove the Text and the use Autosize to limit the clickable surface.
Currently, the Checked state gets changed even if the text label is clicked.
FYI, I cannot remove the Text and the use Autosize to limit the clickable surface.
Not really as the text is part of the checkbox control. Why would you want to limit the User Experience?
ASKER
Hi David, we had user double-clicking on the drop-down part of a datetime picker. The first click had the datetime picker to close and the second click change the state of the checkbox that was "under". the result was catastrophic! We tried to train that user but nothing to do with that stubborn guy!
Zvonko, not sure to understand, the object is the checkbox (which is built from a checkbox and label but we don't have access to that unless I missed something)
Zvonko, not sure to understand, the object is the checkbox (which is built from a checkbox and label but we don't have access to that unless I missed something)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi saige
I was almost ready to accept your solution but did a last test.
When the checkbox control has the focus, and you press the space bar to toggle the checked state, the Mouse Position is checked to be in the boundaries. Anyway to bypass the check when the space bar is pressed?
I was almost ready to accept your solution but did a last test.
When the checkbox control has the focus, and you press the space bar to toggle the checked state, the Mouse Position is checked to be in the boundaries. Anyway to bypass the check when the space bar is pressed?
Ultimately, it depends on whether or not your end users will have different display settings, especially any with DPI or accessibility adjustments. For example, recent versions of Windows allows someone with a small laptop screen to make everything bigger, so a checkbox might take 20 pixels instead of 10.
Personally, I think it's always just a matter of time until that situation comes up, and then you're having to figure out how to fix it all over again.
That in mind, your best scenario is to...
1. Fire the person.
Just kidding.
2. Try to adjust saige's comment to utilize the Bounds property to determine length and then check the cursor based on a percentage rather than a pixel. That should help account for DPI/accessibility adjustments.
3. Use a separate text / label control for the label of the checkbox and clear the checkbox text.
4.If you can't modify the checkbox's label, place another label control over top of it (same text and format, but if they click on it, they'll be clicking on the top label).
5.(ugh) Use a timer to disable clicks on the checkboxes for 200 milliseconds after they select a date.
EDIT:
Just noticed your previous comment about the spacebar - just detect the key down and key up events. If the key is down then skip the mouse check.
Personally, I think it's always just a matter of time until that situation comes up, and then you're having to figure out how to fix it all over again.
That in mind, your best scenario is to...
1. Fire the person.
Just kidding.
2. Try to adjust saige's comment to utilize the Bounds property to determine length and then check the cursor based on a percentage rather than a pixel. That should help account for DPI/accessibility adjustments.
3. Use a separate text / label control for the label of the checkbox and clear the checkbox text.
4.If you can't modify the checkbox's label, place another label control over top of it (same text and format, but if they click on it, they'll be clicking on the top label).
5.(ugh) Use a timer to disable clicks on the checkboxes for 200 milliseconds after they select a date.
EDIT:
Just noticed your previous comment about the spacebar - just detect the key down and key up events. If the key is down then skip the mouse check.
My testing cannot replicate that issue. If the mouse is not directly over the boundaries of the checkbox, it shows that the boundaries were missed.
Are you saying that you want the space bar keypress to toggle the checkbox?
-saige-
Are you saying that you want the space bar keypress to toggle the checkbox?
-saige-
change the state of the checkbox that was "under". the result was catastrophic
how about moving that box slightly down?
how about moving that box slightly down?
ASKER
The control is part of a form that is created dynamically from the fields in a database. all controls are displayed in a scrolling panel. So I cannot move the controls around to prevent that situation.
>>Are you saying that you want the space bar keypress to toggle the checkbox?
It is the normal behavior of the checkbox that when it has focus, pressing the space bar toggles the checked state
>>Are you saying that you want the space bar keypress to toggle the checkbox?
It is the normal behavior of the checkbox that when it has focus, pressing the space bar toggles the checked state
ASKER
I have something that I will continue to test tomorrow!
I am now handling the KeyPress event in addition to the boundary check.
Yes it is for the Infragistics UltraCheckEditor (which does not have an Autocheck property) but have been able to figure it out. Works mostly the same with a regular checkbox.
I am now handling the KeyPress event in addition to the boundary check.
Yes it is for the Infragistics UltraCheckEditor (which does not have an Autocheck property) but have been able to figure it out. Works mostly the same with a regular checkbox.
Private Sub UltraCheckEditor2_BeforeCheckStateChanged(sender As Object, e As CancelEventArgs) Handles UltraCheckEditor2.BeforeCheckStateChanged
Dim chk = TryCast(sender, UltraCheckEditor)
If chk.Tag = "SKIP BOUNDARY CHECK" Then
chk.Tag = String.Empty
Return
End If
Dim point = New Point(MousePosition.X, MousePosition.Y)
Dim position = PointToScreen(chk.Location)
Dim boundaries = New Func(Of Boolean)() {Function() point.X >= position.X, Function() point.X <= position.X + 15, Function() point.Y >= position.Y, Function() point.Y <= position.Y + 15}
If boundaries.All(Function(x) x.Invoke()) Then
TextBox1.Text = $"Checkbox Boundaries clicked at {point} - {position}"
'chk.Checked = Not chk.Checked
Else
TextBox1.Text = $"MISSED Checkbox Boundaries at {point} - {position}"
e.Cancel = True
End If
End Sub
Private Sub UltraCheckEditor2_KeyPress(sender As Object, e As KeyPressEventArgs) Handles UltraCheckEditor2.KeyPress
If e.KeyChar = Convert.ToChar(Keys.Space) Then
UltraCheckEditor2.Tag = "SKIP BOUNDARY CHECK"
End If
End Sub
Do you get same object reference when clicking on label and on box?