views:

515

answers:

3

I want to create a custom container control in ASP.NET (similar to a Panel) with a check box as a header that disables all contained controls when unchecked.

How would I go about doing this?

EDIT:

To expand on my requirements, I need something like Rob suggested, i.e. a UserControl containing a CheckBox and a content panel. However, it should be functionally similar to a Panel, in that I need to be able to reuse the control, defining different contents in each instance of it. It's hard to explain, sorry for the apparent "feature creep."

+2  A: 

If I recall correctly, you disable the panel [using the enabled property] when the checkbox is unchecked, this will disable the items within the panel. You don't then need to disable all the items within the panel individually. Likewise, when you enable the panel again, it will re-enable the child controls.

myPanel.Enabled = false; //Child controls disabled
myPanel.Enabled = true; //Child controls enabled

You could also iterate each control within the panel using:

foreach(Control control in myPanel)
{
    //Assume for the purpose of demonstration 
    //that each control within myPanel has an
    //"Enabled" property
    control.Enabled = myPanel.Enabled;
}

This would set the enabled property of each control within the panel to match that of the panel - really, this is surplus to requirement and therefore isn't really desirable. I just provided this method for demonstration purposes.

Edit: This could be extended [for example] by Rob's design for a user control which you could add a property to your user control to expose the panel's controls collection:

public Control[] Controls
{
    return controlPanel.Controls;
}

This would essentially allow modification of your control's panel controls from outside your user control and not require the controls to be assigned in the panel definition inside the user control.

BenAlabaster
+2  A: 

I would create a UserControl with the following:

<asp:UpdatePanel ID="upDisableAllPanel" UpdateMode="Conditional" runat="server">
    <ContentTemplate>
        <asp:CheckBox AutoPostBack="true" ID="cbTogglePanel" runat="server" />
        <asp:Panel ID="pnlDisableAll" runat="server">
    ... controls here ...
        </asp:Panel>
    </ContentTemplate>
</asp:UpdatePanel>

In the code-behind add this (VB sample)

Public MyControls As New ControlCollection(Me)

Protected Sub control_load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    bindControls()
End Sub

Protected Sub cbTogglePanel_CheckChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles cbTogglePanel.CheckChanged
    pnlDisableAll.Enabled = cbTogglePanel.Checked 'Or Not cbTogglePanel.Checked depending on how you have the cb labeled.'
End Sub

Public Sub bindControls()
    If MyControls IsNot Nothing And MyControls.Count > 0 Then
        pnlDisableAll.Controls.Clear()
        For Each cntrl As Control In MyControls
            pnlDisableAll.Controls.Add(cntrl)
        Next
    End If
End Sub

@balabaster is correct that disabling the panel will effectively disable everything inside. This encapsulates it into a reusable container.

This code assumes you are using .Net 3.5 or .Net 2 with the Ajax.Net library and have a ScriptManager declared somewhere in the content page or Master page. You are using Ajax right?

Rob Allen
Nice tidy solution, worth noting though that you don't *need* Ajax for your solution to work, it would just make it a little more user friendly.
BenAlabaster
I am constantly being accused of being too nice to my users.
Rob Allen
+1 though for a good example of how to implement this
BenAlabaster
lol @Rob, you and me both. I always seem to design my software as a user advocate, drives some programmers nuts though.
BenAlabaster
Thats looks good, however do all the ...controls here... have to be defined within the user control? I need a generic control to which I can add controls within the page the control is defined in.
Patrick McDonald
@Patrick McDonald: In this method, yes. All of the controls would have to be part of the UserControl. You may be able to add controls dynamically from your code behind but that is messier than not useing a UserControl. In your case, I think you would want to extend the Panel class although I do not know how to add the checkbox automatically for a custom class.
Rob Allen
@Patrick - No you could just expose the controls of your panel object in through a public usercontrol "Controls" property and then modifying your UserControl's Controls collection is really modifying your panel within the UserControl's Controls collection so they could be added through the main page.
BenAlabaster
@Rob - You could use your defined UserControl but expose the panel's Controls collection as a property of your UserControl... that way you don't have to get so messy.
BenAlabaster
@Rob and @balablaster, thanks I'll try your suggestions
Patrick McDonald
+1  A: 

I think I would go about this problem differently, I don't think the UserControl with a Panel/Checkbox inside it will work the way you want it to because you won't be able to add other controls into it easily.

Instead, I would create an Ajax Extender for the Checkbox control supply a Panelas an argument to it. Then, whenever the Checkbox was clicked, have it visit each of the Panels child controls with code something like this;

foreach(Control c in pnlFoo.Controls)
{
   if (!(c is Checkbox)) // probably need a better check than this
   {                   // incase you have other checkboxes inside your panel
      c.Enabled = chkToggler.Checked;
   }
}
Kirschstein