On Thu, 31 May 2007 14:24:33 -0700, Peter Duniho
<Np*********@nnowslpianmk.comwrote:
For what it's worth, I did realize that you can set the
RadioButton.AutoCheck property to false to disable the auto-checking
behavior. However, if you do this, you'll have to explicitly handle all
of the related behavior, including treating a group of radio buttons as
a group.
I've got to say, I cannot explain why this question intrigues me so much..
I really ought to be doing other things, but I can't stop playing with it.
Anyway...see below for some code that does what I think you're asking
for. Some notes:
0) The code assumes that you have only radio buttons within the
containing parent. In this case a GroupBox named "groupBox1". If you
wanted to generalize the code, you would need to change the code that
figures out the next control in the tab order to deal with the possibility
of non-RadioButton controls in the group, and/or groups of controls for
which you don't want the Return key to behave this way.
1) The Click handler is required because for this to work you need to
disable the default functionality by setting the AutoCheck property of
each RadioButton instance to false. With that disabled, you need to
handle the checking behavior yourself.
2) I find the need to use a flag to disable behavior in the Click
handler to be a bit kludgy. But since it appears to me that the Click
event is auto-generated in response to a Control getting the focus, I
don't see any immediate way around that.
3) For some reason, the focus rectangle is not displayed until you
first use the Tab key to move focus to the group. However, this is the
default behavior even when AutoCheck is true, so at least my code isn't at
fault for that. But it does produce a kind of strange situation in which
you use the Return key to change the focus, but there's no UI feedback
indicating that. Normally it wouldn't be a problem because the checked
state of the buttons would change, providing that feedback. You will
probably want to figure out if there's a way to make the focus rectangle
show up. I presume the basic mechanism to do that is simple, though I
don't know what the magic incantation is off the top of my head. :)
On this point #3, I found a thread on MSDN that suggests that this is not
the only place one runs into this strange behavior. It appears that the
window controls (either in .NET or, more likely, Windows itself) have a
general problem that until you switch focus using the Tab key, the focus
rectangle is not shown. I think there may be a way to change the behavior
if you make a new radio button class that derives from RadioButton, and
then either set the ShowFocusCues property to "true" or provide a way to
call the OnChangeUICues() method to explicitly have the focus rectangle
shown. But in the interest of not investing even more time in someone
else's attempt to bypass the standard UI behavior :), I've decided to not
bother trying that. :)
4) I make no claims that I have in this code handled all of the subtle
issues that may exist with respect to the selection and focus-changing.
It *seems* to work fine for me, but I easily could have missed something..
The fact that I could have is one of the reasons I try to avoid doing this
sort of "change the standard UI to be non-standard" thing.
Here's the code I came up with (I promise I'm done fiddling with this
now...sorry for all the different replies :) ):
private bool _fEnterKey;
protected override bool ProcessDialogKey(Keys keyData)
{
if (keyData == Keys.Return)
{
int ictl = groupBox1.Controls.IndexOf(ActiveControl);
if (ictl != -1)
{
Control ctlFocus = groupBox1.Controls[(ictl
+ groupBox1.Controls.Count - 1) % groupBox1.Controls.Count];
_fEnterKey = true;
ActiveControl.TabStop = false;
ctlFocus.TabStop = true;
ctlFocus.Focus();
_fEnterKey = false;
}
}
return base.ProcessDialogKey(keyData);
}
private void radioButton1_Click(object sender, EventArgs e)
{
GroupBox grp = (GroupBox)((Control)sender).Parent;
if (!_fEnterKey && grp != null)
{
foreach (RadioButton radio in grp.Controls)
{
if (radio != sender)
{
radio.TabStop = false;
radio.Checked = false;
}
}
((Control)sender).TabStop = true;
((RadioButton)sender).Checked = true;
}
}