【问题标题】:How do I create a custom panel with a checkbox in ASP.NET如何在 ASP.NET 中创建带有复选框的自定义面板
【发布时间】:2009-05-27 16:19:07
【问题描述】:

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

我该怎么做呢?

编辑:

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

【问题讨论】:

    标签: asp.net controls containers


    【解决方案1】:

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

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

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

      此代码假定您正在使用带有 Ajax.Net 库的 .Net 3.5 或 .Net 2,并且在内容页或母版页的某处声明了 ScriptManager。您正在使用 Ajax 对吗?

      【讨论】:

      • 漂亮整洁的解决方案,值得注意的是,您的解决方案不需要 Ajax 来工作,它只会让它对用户更友好一点。
      • 我经常被指责对我的用户太好。
      • 大声笑@Rob,你和我都是。我似乎总是以用户倡导者的身份设计我的软件,但让一些程序员发疯。
      • 看起来不错,但是这里的所有...控件...都必须在用户控件中定义吗?我需要一个通用控件,我可以在定义控件的页面中添加控件。
      • @Patrick McDonald:在这种方法中,是的。所有控件都必须是 UserControl 的一部分。您可能能够从您的代码中动态添加控件,但这比不使用 UserControl 更混乱。在您的情况下,我认为您希望扩展 Panel 类,尽管我不知道如何为自定义类自动添加复选框。
      【解决方案3】:

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

      相反,我将为Checkbox 控件创建一个Ajax Extender,并为其提供Panel 作为参数。然后,每当单击 Checkbox 时,让它访问每个 Panels 子控件,代码如下;

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-18
        • 1970-01-01
        相关资源
        最近更新 更多