如何在 ASP.NET 中创建带有复选框的自定义面板

How do I create a custom panel with a checkbox in ASP.NET

提问人:Patrick McDonald 提问时间:5/28/2009 最后编辑:Patrick McDonald 更新时间:5/28/2009 访问量:1648

问:

我想在 ASP.NET 中创建一个自定义容器控件(类似于 Panel),其中包含一个复选框作为标题,在取消选中时禁用所有包含的控件。

我该怎么做?

编辑:

为了扩展我的要求,我需要 Rob 建议的东西,即包含 CheckBox 和内容面板的 UserControl。但是,它在功能上应该类似于 Panel,因为我需要能够重用控件,在它的每个实例中定义不同的内容。这很难解释,对不起明显的“功能蠕变”。

asp.net 控制 容器

评论


答:

2赞 BenAlabaster 5/28/2009 #1

如果我没记错的话,当取消选中复选框时,您禁用面板 [使用 enabled 属性],这将禁用面板中的项目。然后,您无需单独禁用面板中的所有项目。同样,当您再次启用该面板时,它将重新启用子控件。

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

还可以使用以下方法迭代面板中的每个控件:

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

这会将面板中每个控件的 enabled 属性设置为与面板的属性匹配 - 实际上,这超出了要求,因此并不需要。我只是出于演示目的提供了此方法。

编辑:例如,Rob 对用户控件的设计可以对此进行扩展,您可以向用户控件添加属性以公开面板的控件集合:

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

这实质上允许从用户控件外部修改控件的面板控件,而不需要在用户控件内的面板定义中分配控件。

2赞 Rob Allen 5/28/2009 #2

我将创建一个具有以下内容的 UserControl:

<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>

在代码隐藏中,添加以下内容(VB 示例)

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正确,禁用面板将有效地禁用内部的所有内容。这会将其封装到可重复使用的容器中。

此代码假定您使用 .Net 3.5 或 .Net 2 和 Ajax.Net 库,并在内容页或母版页中的某个位置声明了 ScriptManager。您正在使用 Ajax,对吗?

评论

0赞 BenAlabaster 5/28/2009
不错整洁的解决方案,值得注意的是,虽然您不需要 Ajax 来运行您的解决方案,但它只会使其更加用户友好。
0赞 Rob Allen 5/28/2009
我经常被指责对我的用户太好了。
0赞 BenAlabaster 5/28/2009
哈哈@Rob,你和我都。我似乎总是以用户拥护者的身份设计我的软件,这让一些程序员发疯了。
0赞 Patrick McDonald 5/28/2009
这看起来不错,但是所有......控制在这里...必须在用户控件中定义吗?我需要一个泛型控件,可以在定义控件的页面中添加控件。
1赞 Rob Allen 5/28/2009
@Patrick McDonald:在这种方法中,是的。所有控件都必须是 UserControl 的一部分。您可以从代码隐藏中动态添加控件,但这比不使用 UserControl 更麻烦。在您的情况下,我认为您会想要扩展 Panel 类,尽管我不知道如何为自定义类自动添加复选框。
1赞 Kirschstein 5/28/2009 #3

我想我会以不同的方式解决这个问题,我不认为里面有面板/复选框的 UserControl 会按照您想要的方式工作,因为您将无法轻松地将其他控件添加到其中。

相反,我会为控制电源 a 创建一个 Ajax 扩展器作为它的参数。然后,每当单击 时,让它访问每个子控件,代码如下;CheckboxPanelCheckboxPanels

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;
   }
}