views:

94

answers:

2

I'm using C++ Builder 5. Is there a way to group a disparate set of controls so that by simply calling, for instance, myGroup.Enabled = false; will set all group of controls enabled property to false? I can't use a GroupBox since the controls (labels, checkboxes, etc) are on different TabPages.

The reason I ask is so I don't have to call each control's enabled property explicitly and can do it with one simple call.

If not, how can I create a custom Control class to do this?

+1  A: 

You could use the Tag property of the controls and create your own grouping.

void TForm1::SetControlState(TWinControl *WinCtrl, const bool IsEnabled, const int TagValue)
{
 // set the enabled property for each control with matching TagValue
 for (int Index = 0; Index < WinCtrl->ControlCount; ++Index)
 {
   if (WinCtrl->Controls[Index]->Tag == TagValue)
   {
     WinCtrl->Controls[Index]->Enabled = IsEnabled;
   }

   // set child controls
   if (WinCtrl->Controls[Index]->InheritsFrom(__classid(TWinControl)))
   {
     TWinControl *TempWinCtrl;
     TempWinCtrl = static_cast<TWinControl *>(WinCtrl->Controls[Index]);
     SetControlState(TempWinCtrl, IsEnabled, TagValue);
   }
 } // end for
}

Alternatively, If you want to enable/disable all controls in one go.

void TForm1::SetControlState(TWinControl *WinCtrl, const bool IsEnabled)
{
 // set the enabled property for each control with parent TabSheet
 for (int Index = 0; Index < WinCtrl->ControlCount; ++Index)
 {
   WinCtrl->Controls[Index]->Enabled = IsEnabled;

   // disable child controls
   if (WinCtrl->Controls[Index]->InheritsFrom(__classid(TWinControl)))
   {
     TWinControl *TempWinCtrl;
     TempWinCtrl = static_cast<TWinControl *>(WinCtrl->Controls[Index]);
     SetControlState(TempWinCtrl, IsEnabled);
   }
 } // end for
} 

Examples:

// disable all controls on the form
SetControlState(Form1, false);

// disable all controls on a tabsheet
SetControlState(TabSheet1, false);

NOTE: The above code has been tested with C++Builder 2007

stukelly
When comparing the tabsheets, may I ask why you wish to compare by name, and not just compare the pointers? Should be a lot faster.
TommyA
@TommyA: Thanks, I've changed the code. I'm not sure why I was comparing the controls by name. I copied my first example, so I probably didn't read the code fully.
stukelly
Is Form1->Controls[..] the correct syntax?
0A0D
@Roboto. The syntax is correct, however I was not disabling child controls. I have updated my answer and the code should work.
stukelly
Well a recursive structure as you are using now seems obvious. But actually setting a controls Enabled property will already set that of the child controls as well, so there should be no need for it. However it is a good idea to send an initial control, so you are not bound to Form1.
TommyA
this seems to work but the controls don't update properly.. i tried calling Update() but no effect.. I change tabs and it refreshes properly.. when I call Enabled explicitly by naming the control, this issue does not happen - weird
0A0D
@Roboto: Try Application->ProcessMessages() at the end or adding WinCtrl->Controls[Index]->Invalidate() after the Enabled property is set.
stukelly
@stukelly: I'll try that.. I did ->Repaint() and ->Update() which should invalidate the controls.
0A0D
@stukelly: It only affects labels that are in nested tabs. Any clues? I followed your suggestions but I can't get it to work.
0A0D
@Roboto: I have tested with C++Builder 6 and it works with the above code. What do you mean "labels that are in nested tabs"?
stukelly
@stukelly: Take a form, create a pagecontrol, add tabs, now in one tab page, make another set of tabs (like a subsection). The label does not update if it is on one of the nested tab pages.
0A0D
+2  A: 

Since the controls you want to group are not in the same container, then I suggest using a TAction (look at the TActionList component). All TControl descendants have a public (sometimes even published) Action property. You can have the same TAction object assigned to multiple controls at the same time. Enabling/disabling the TAction (or updating any of its other properties) will automatically update all associated controls accordingly.

Remy Lebeau - TeamB