MFC and Radio Buttons
DOUG MILLER -- DOUGM@omnicell.com
Monday, January 22, 1996
(Currently using MFC 3.0, VIsual C++ 2.0)
First I would like to point out that I like the DDX_Radio functionality
of
MFC and radio buttons. But what I can't find is an easy way to enable
(or disable) radio buttons based on the current state of an app, or
similarily how to check/uncheck radio buttons.
i.e., you have multiple groups of radio buttons. In the 1st group you
have
buttons A, B and C. In the second group you have buttons D, E, F, G. If
button A is selected, only buttons D or E are valid choices. If button B
is
selected, only button F is a valid choice, etc. Other than using
GetDlgItem(E)->EnableWindow(FALSE); and then using the
GetCheckedRadioButton() method, followed by appropriate calls to
((CButton*)GetDlgItem(E))->SetCheck(0); to remove the checked state of
any of the newly disabled buttons, does anyone have a more efficient way
of setting the enabled and checked states of radio buttons in a dialog?
Is
the preceeding even the suggested way of doing what I described wanting
to do?
Thanks for all suggestions.
---
With scissors, there can be no good haircuts.
Mike Blaszczak -- mikeblas@interserv.com
Wednesday, January 24, 1996
[Mini-digest: 4 responses]
On Mon, 22 Jan 1996, DOUG MILLER wrote:
>i.e., you have multiple groups of radio buttons. In the 1st group you
>have
>buttons A, B and C. In the second group you have buttons D, E, F, G. If
>button A is selected, only buttons D or E are valid choices. If button B
>is
>selected, only button F is a valid choice, etc. Other than using
>GetDlgItem(E)->EnableWindow(FALSE); and then using the
>GetCheckedRadioButton() method, followed by appropriate calls to
>((CButton*)GetDlgItem(E))->SetCheck(0); to remove the checked state of
>any of the newly disabled buttons, does anyone have a more efficient way
>of setting the enabled and checked states of radio buttons in a dialog?
> Is
>the preceeding even the suggested way of doing what I described wanting
>to do?
If it was me, I would write code that made calls to functions like
EnableWindow() and SetCheck() and GetCheckedRadioButton() from the BN_CLICKED
handler of each button. If my box didn't have other complicated validation,
I would call UpdateData() from that handler first, and then use the member
variables to decide what buttons to enable or disable. If my box _did_ have
other complicated validation, I would break the code to DDX_ on the radio
buttons into a separate function so I could call it easily from my
DoDataExchange() and from all my OnSomeButton() functions.
>With scissors, there can be no good haircuts.
Have I been doing things wrong all these years?
.B ekiM
--
TCHAR szBackEast[] = _T("It's a hockey night in Hartford!");
-----From: "Greg D. Tighe"
Another good way of implementing this type of functionality is to
replace the second group of radio buttons with a dropdown listbox
which is populated only with valid choices based upon the currently
selcted radio button from the first group.
(You can of course also replace the first group of radio buttons with
a dropdown listbox.)
-Greg T.
-----From: Marty Fried
The way I handle this is to create a 2nd variable from the same ID, but create
it as a control type, rather than numeric (DDX_Control, I think).
Then I use this member to access the control. And a message handler for the
control message, to know when it's been pressed.
-----From: Brad Wilson
Put BN_CLICKED handlers for the radio buttons and enable/disable the choices
at that time.
If you have DDX_Radio handlers for these buttons, you can select a particular
button by calling UpdateData(TRUE) to put the data into your member variables,
then changing the integer index that you want to change, then calling
UpdateData(FALSE) to set the data back into the dialog. For instance, here
could be your handler for ON_BN_CLICKED for button B:
void MyDialog::OnB()
{
UpdateData( TRUE );
m_MyIndexForDEFG = 3;
UpdateData( FALSE );
((CButton*)GetDlgItem(D)) -> EnableWindow( FALSE );
((CButton*)GetDlgItem(E)) -> EnableWindow( FALSE );
((CButton*)GetDlgItem(F)) -> EnableWindow( TRUE );
((CButton*)GetDlgItem(G)) -> EnableWindow( FALSE );
}
You can make that code look cleaner by adding CButton members for D, E, F
and G, which would make the last four lines look like:
m_MyD.EnableWindow( FALSE );
m_MyE.EnableWindow( FALSE );
m_MyF.EnableWindow( TRUE );
m_MyG.EnableWindow( FALSE );
Good luck!
Brad
--
class CBradWilson : public CWorldWatchProgrammingTeam {
public:
void GetInetAddr ( CString& s ) { s = "bradw@exptech.com"; }
void GetE164Addr ( CString& s ) { s = "+1 (810) 620-9803"; }
void GetURL ( CString& s ) { s = "http://www.exptech.com"; }
void GetDisclaimer( CString& s ) { s = "All I say is fact :-p"; }
};
// QOTW: "Don't think of yourself as the least intelligent creature in this
// room ... if you consider the entire planet, you're smarter than
// literally hundreds of people." - Dogbert to Dilbert
Niels Ull Jacobsen -- nuj@kruger.dk
Monday, January 29, 1996
>
> [Mini-digest: 4 responses]
[I've cut a few]
>
> Another good way of implementing this type of functionality is to
> replace the second group of radio buttons with a dropdown listbox
> which is populated only with valid choices based upon the currently
> selcted radio button from the first group.
>
> (You can of course also replace the first group of radio buttons with
> a dropdown listbox.)
>
In my opinion this is a rather bad UI, as it is often unclear to the
user which options are available at which time. With two sets of radio
buttons it is simple to find out "If I select A, D and E are
enabled. If I select B, D & F are enabled."
> -Greg T.
> -----From: Brad Wilson
>
> Put BN_CLICKED handlers for the radio buttons and enable/disable the choices
> at that time.
>
> If you have DDX_Radio handlers for these buttons, you can select a
> particular button by calling UpdateData(TRUE) to put the data into
> your member variables, then changing the integer index that you want
> to change, then calling UpdateData(FALSE) to set the data back into
> the dialog. For instance, here could be your handler for
> ON_BN_CLICKED for button B:
>
> void MyDialog::OnB()
> {
> UpdateData( TRUE );
> m_MyIndexForDEFG = 3;
> UpdateData( FALSE );
>
> ((CButton*)GetDlgItem(D)) -> EnableWindow( FALSE );
> ((CButton*)GetDlgItem(E)) -> EnableWindow( FALSE );
> ((CButton*)GetDlgItem(F)) -> EnableWindow( TRUE );
> ((CButton*)GetDlgItem(G)) -> EnableWindow( FALSE );
> }
>
> You can make that code look cleaner by adding CButton members for D, E, F
> and G, which would make the last four lines look like:
>
> m_MyD.EnableWindow( FALSE );
> m_MyE.EnableWindow( FALSE );
> m_MyF.EnableWindow( TRUE );
> m_MyG.EnableWindow( FALSE );
You can make it even cleaner by putting this functionality in your DoDataExchange.
Let's assume that D is always enabled if any of A-C is enabled, E is
enabled if A or B is selected, F is enabled if A or C is, and G is
enabled only if C is selected.
m_ABC is a radio button DDX variable.
CMyDlg::DoDataExcchange(CDataExchange* pDX)
{
... // standard classwizard stuff
if (!pDX->m_bSaveAndValidate)
{
m_MyD.EnableWindow(m_ABC == A || m_ABC == B || m_ABC == C );
m_MyE.EnableWindow(m_ABC == A || m_ABC == B );
m_MyF.EnableWindow(m_ABC == A || m_ABC == C );
m_MyG.EnableWindow( m_ABC == C );
}
}
Of course, we still haven't defined what will happen if the user makes
the current DEFG choice illegal by selecting a new ABC (e.g. selecting
C, G and then A. G is now an illegal choice. The best option here
depends on your application.
> Good luck!
> Brad
--
Niels Ull Jacobsen, Kruger A/S
Everything stated herein is THE OFFICIAL POLICY of the entire Kruger
group and should be taken as legally binding in every respect. Pigs
will grow wings and fly.
| Вернуться в корень Архива
|