Make two checkboxes act as radio buttons.

I’ve got two checkboxes that I want the user to -

  1. Be able to only have one checked at a time (ie. when you check one the other becomes unchecked).
  2. Be able to have both unchecked

I thought it would be a simple matter of having one uncheck the other in each checkbox Action event but then it starts an endless process as the other then unchecks the first.

I suppose I could use three radio buttons for the three different situations but …

Use a window property to distinguish setting the value in code vs. a user click. Set the property before changing the value in code and check the value in the Action event. Be sure to reset the property in Action as well.

CheckBox1

Sub Action()
    If (me.Value = True) And (CheckBox2.Value = True) Then CheckBox2.Value = False
End Sub

CheckBox2

Sub Action()
    If (me.Value = True) And (CheckBox1.Value = True) Then CheckBox1.Value = False
End Sub

Wouldn’t it be better to use the controls the way there are designed to be used?

Solution 1:

[X] Use Options (if unchecked Option A and B should be disabled) ( ) Option A (X) Option B

Solution 2:

code None
( ) Option A
(X) Option B[/code]
[ ] = Checkbox, ( ) = Radiobutton

Thanks Eli I’m sure that works too. As stated in my question I can use three radio buttons but the form I am creating has a long column of checkboxes (like a multiple choice questionnaire).
I want to keep a simple uniform format of controls but where two answers contradict each other I want to allow one answer and automatically uncheck the opposing answer.

The uniform look is not important for the user. Actually it is probably irritating for the user, as he is not accustomed to click on checkbox and then another one is unchecked automatically.

Radio buttons.

And on OS X it would violate Apple’s human interface guidelines.

I see there is an answer already, but this sounds like a job for the segmented control to me…

If you really need to use checkboxes, try using the mousedown/mouseup events. Return true in mousedown and in mouseup, check that the mouse is within the bounds of the control. Then set me.value=not me.value and loop through the others and set value=false. This avoids the infinite loop you had going originally. You could also group the related checkboxes in a parent control (groupbox/canvas/etc) so that you can loop through window.controls() and check each for control(i).parent=me.parent to avoid hardwiring the relationships. You could subclass checkbox and have automatic functionality.

something like

[code]Function MouseDown(X As Integer, Y As Integer) As Boolean
Return true
End Function

Function MouseUp(X As Integer, Y As Integer) As Boolean
if x>0 and x<self.Width and y>0 and y<self.Height then
me.Value=not me.Value
for i as integer=0 to window.ControlCount-1
if window.Control(i) isa CheckBox then
dim nextcontrol as CheckBox=CheckBox(window.control(i))
if nextcontrol<>self and nextcontrol.parent=self.parent then nextcontrol.value=false
end if
next
end if

End Function
[/code]

Though I would recommend disabling the contradictory selection rather than unchecking it.