【问题标题】:Creating a collapsable area in ASP.NET在 ASP.NET 中创建可折叠区域
【发布时间】:2010-12-15 09:51:45
【问题描述】:

目前我已经构建了一个collapseControl,它的行为类似于一个标签(associatedControlID)来控制一个控件的折叠状态。

我想要构建的以下控件:

collapsableArea http://img692.imageshack.us/img692/3307/stackoverflowcollapseab.jpg

我想到了类似的东西:
将我已经构建的 collapsableControl 和其他一些控件(例如面板)放在一起以获得 collapsableArea。

第一次尝试:
我尝试扩展面板并执行以下操作:

this.Parent.Controls.Add(collapsableControl);

但这给了我:“不正确的生命周期步骤”,“无法修改”,“nullReference”,......异常

所以我又试了一次(我认为这是更好的选择,因为没有 tagKey):
我扩展了一个占位符并执行了以下操作:

this.Controls.Add(collapsableControl);
this.Controls.Add(collapsablePanel);

这导致了其他问题,例如:我只想设置面板的文本,面板的样式,...

有线!

对于这种情况你有什么解决方案吗?

编辑:
我想出了另一个解决方案:
another solution http://img109.imageshack.us/img109/3307/stackoverflowcollapseab.jpg

“CollapsableArea”属于“Control”类型,包含 2 个额外的私有属性:

  1. “可折叠控件”
  2. “面板”

我认为将 CollapsableArea.Controls 的 getter 重定向到 CollapsableArea.Panel.Controls 就足够了。在 CollapsableArea.CreateChildControls() 我实例化并添加 CollapsableControl 和 Panel 到 base.Controls 并在 CollapsableArea.RenderChildren() 渲染那些 2

我现在的问题: CollapsableControl 将获得一个 clientID(不设置 ID) - 面板不会 如果面板包含 -tags

,则呈现 CollapsableControl 将失败(或传递出去)

有什么建议吗?

编辑: 我修复了丢失 ID 的行为 - 只需将 CollapsableControl.AssociatedControlID 设置为 Panel.ClientID... 但是 - 当将 放入面板时,它不会被渲染??!!

【问题讨论】:

    标签: asp.net collapse web-controls asp.net-webcontrol


    【解决方案1】:

    如果您想要一个简单的面板,而不是重新发明轮子,您可以使用可折叠面板控件:

    http://www.asp.net/AJAX/AjaxControlToolkit/Samples/CollapsiblePanel/CollapsiblePanel.aspx

    可能是获得所需功能的最简单方法?

    【讨论】:

    • 我知道有这个控件,但是:我们既不想使用 atlas-framework 也不想使用它的控件……对不起!加:我们不需要这样一个唱歌跳舞的控件……我们专注于jQuery的集成!
    • 您可能会以更常见的方式看到“您的解决方案是什么”的问题 - 我认为将 2 个控件组合在一起是一种广泛使用的场景!从现在开始我不知道这种情况的(最佳)解决方案:)
    【解决方案2】:

    哦,怎么回事 - 我已经解决了这个问题:

    public sealed class CollapsableArea : Control
    {
        private const string ViewStateKeyCollapsableContentClientID = "collapsableContentClientID";
    
        private string CollapsableContentClientID
        {
            get
            {
                var obj = this.ViewState[ViewStateKeyCollapsableContentClientID];
                if (obj == null)
                {
                    var collapsableContentClientID = Guid.NewGuid().ToString();
                    this.ViewState[ViewStateKeyCollapsableContentClientID] = collapsableContentClientID;
                    return collapsableContentClientID;
                }
                return (string)obj;
            }
        }
    
        /// <summary>
        /// Gets or sets the header text.
        /// </summary>
        /// <value>The header text.</value>
        public string HeaderText
        {
            get
            {
                this.EnsureChildControls();
                return this._collapseControl.Text;
            }
            set
            {
                this.EnsureChildControls();
                this._collapseControl.Text = value;
            }
        }
    
        public override ControlCollection Controls
        {
            get
            {
                // redirect controls
                return this._collapsableContent.Controls;
            }
        }
    
        #region child controls
    
        private readonly Panel _collapsableContent = new Panel();
        private readonly CollapsableControl _collapseControl = new CollapsableControl();
    
        #endregion
    
        public override Control FindControl(string id)
        {
            // need to redirect
            if (string.Equals(id, this._collapsableContent.ID))
            {
                return this._collapsableContent;
            }
            return this._collapsableContent.FindControl(id);
        }
    
        protected override void CreateChildControls()
        {
            base.Controls.Clear();
    
            var collapsableContentClientID = this.CollapsableContentClientID;
            this._collapsableContent.ID = collapsableContentClientID;
            this._collapseControl.AssociatedControlID = collapsableContentClientID;
            base.Controls.Add(this._collapseControl);
            base.Controls.Add(this._collapsableContent);
        }
    
        protected override void RenderChildren(HtmlTextWriter writer)
        {
            this._collapseControl.RenderControl(writer);
            // hack for code blocks
            if (!this.Controls.IsReadOnly)
            {
                this._collapsableContent.RenderControl(writer);
            }
            else
            {
                this._collapsableContent.RenderBeginTag(writer);
                base.RenderChildren(writer);
                this._collapsableContent.RenderEndTag(writer);
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      您的控件应该获得一个模板控件属性来定义可折叠的内容。正如您所说,获取 Label 控件 ID 的 AssociatedControlID 属性。

      public class CollapsableArea : WebControl, INamingContainer
      {
          public string AssociatedControlID { get; set; }
          public ITemplate ContentTemplate { get; set; }
      }
      

      您必须在页面的启动脚本中注册一个 jquery。

      $("#The AssociatedControlID client control id").click(function(e) {
          $("#The CollapsableArea client control id").toggle();
      }
      

      【讨论】:

      • 不...因为我想要一个包含 2 个控件(collapsableControl,面板)的控件,我知道 @CreateChildControls 控件的 ID,用于 collapsableControl 的关联控件 ID。我实施的 collapsableControl 已经捕获了您的解决方案 - 但出于短路原因,我想创建一个 collapsableArea ...
      • "shorting-reason":collapsableControl 的 80% 使用率将与普通的旧面板结合使用。如果只有一个,为什么每个程序员都应该声明 2 个控件?
      • 我意识到您有一个 CollapsableControl,它可以展开和折叠关联的面板。 CollapsableArea 在这里的作用是什么?
      • “collapsableArea”是想要的控件,包含一个 collapsableControl(它是带有图标的标题)和例如。一个面板(用于内容) - 请参阅编辑了解更多信息!
      • 基本上我不同意你的模型。这个控件比你写的要容易得多。
      猜你喜欢
      • 1970-01-01
      • 2012-12-01
      • 1970-01-01
      • 2020-09-19
      • 1970-01-01
      • 2013-06-02
      • 1970-01-01
      • 2017-12-14
      • 1970-01-01
      相关资源
      最近更新 更多