【问题标题】:Custom ASP.net Server Controls - Rendering自定义 ASP.net 服务器控件 - 渲染
【发布时间】:2009-03-21 07:48:18
【问题描述】:

我目前正在 ASP.net 中编写自定义服务器控件。我的想法是创建某种可折叠的面板控件(顺便说一句,这是我正在编写的第一个服务器控件)。所以我想要的是用户在页面中以这种方式定义我的控件:

<myCtrl:CollapsiblePanel id="myCollapsiblePanel" runat="server">
   <asp:Label id="lblTest" runat="server" Text="Test Label:"/>
   <asp:TextBox id="txbTest" runat="server"/>
</myCtrl:CollapsiblePanel>

然后控件应呈现在最终页面上,如下所示:

<div id="myCollapsiblepanel">
   <input type="submit" name="btnExpand" value="Expand/Collapse" id="btnExpand" />
    <div id="pnlContent"> 
       <span id="lblTest">Title:</span> 
       <input name="txbTest" type="text" id="txbTest" /> 
    </div>
</div>

提交按钮“btnExpand”在控件上有一个事件处理程序,用于隐藏/显示面板“pnlContent”。 我的第一种方法是创建一个继承自 Panel 的服务器控件。在 CollapsiblePanel 控件中,我创建了另一个面板“pnlContent”。在 OnInit 我做了如下的事情:

protected override void OnInit(EventArgs e)
{
   for (int i = 0; i < base.Controls.Count; i++)
   {
       Control control = base.Controls[i];
       content.Controls.Add(control);
   }
   base.Controls.Clear();

   base.Controls.Add(button);
   base.Controls.Add(content);
}

我基本上将当前存在于我的控件中的所有控件添加到内部创建的 Panel pnlContent 的控件列表中。此外,我添加了一个按钮,该按钮然后执行 pnlContent 的扩展/折叠。 我的问题是渲染无法正常工作。按钮和 pnlContent 正确呈现,只是 pnlContent 内的控件未显示。输出如下

<div id="myCollapsiblepanel">
   <input type="submit" name="btnExpand" value="Expand/Collapse" id="btnExpand" />
    <div id="pnlContent"> </div>
</div>

pnlContent 为空... 有人可以建议我解决这个问题和/或我在渲染上做错了什么。我没有覆盖我继承的 Panel 的默认呈现,因为我认为这不是必需的,因为我在 OnInit 中修改了它的控制结构,所以它应该呈现我的修改..

目前我找到了解决方案。我基本上按照 Microsoft Ajax Control 工具包中最常见的方式进行操作。我创建了一个所谓的“扩展器”,它不会呈现自身,而只是添加行为。所以现在我将要折叠的面板的 id 添加到我的 CollapsiblePanelExtender 控件中,然后它就完成了折叠/展开的工作。也许这也是更好、更清洁的解决方案,但我仍然想知道我之前描述的第一种方法出了什么问题。

感谢您的帮助!

【问题讨论】:

    标签: asp.net controls


    【解决方案1】:

    这是因为在任何给定时刻一个控件只能属于一个父级。当您将控件从一个集合添加到另一个集合时,它会自动从第一个集合中删除。在你的情况下:

    for (int i = 0; i < Controls.Count; i++)
    {
       //obtain a reference
       Control control = Controls[i];
       //The control is removed from Controls collection 
       //and added to content.Controls. All remaining controls get shifted left.
       //This means that next control will get skipped.
       content.Controls.Add(control);
    }
    

    考虑执行以下操作(顺便说一下,在这种情况下您可能不需要使用 base):

    Control[] controls = new Control[Controls.Count];
    Controls.CopyTo(controls, 0); //create a snapshot of controls
    
    for (int i = 0; i < controls.Length; i++)
        content.Controls.Add(controls[i]);
    

    或使用反向加法:

    Control[] controls = new Control[Controls.Count];
    for (int i = Controls.Count - 1; i >= 0; i--) //walk backwards
        controls[i] = Controls[i];
    
    for (int i = 0; i < controls.Length; i++)
        content.Controls.Add(controls[i]);
    

    【讨论】:

    • 我太傻了 :) 我应该意识到我的控件集合被修改了(至少当我在运行时使用 foreach 循环时遇到编译器错误时)。感谢您的提示!
    【解决方案2】:

    弄乱 Controls 集合,尤其是在 Control 容器之间删除和交换控件并不总是有效。

    您是否特别不想在回发之前呈现内容?为什么不渲染控件并在 CSS 上使用 display:none 将它们包装在一个 div 中,然后可以使用 jQuery 之类的简单工具在客户端交换?

    例如

    <myCtrl:CollapsiblePanel id="myCollapsiblePanel" runat="server" Text="Panel title">
       <asp:Label id="lblTest" runat="server" Text="Test Label:"/>
       <asp:TextBox id="txbTest" runat="server"/>
    </myCtrl:CollapsiblePanel>
    

    您可能应该在 CreateChildControls 重载中创建应用它:

    protected override CraeteChildControls() 
    {
        Controls.Add(new LiteralControl("<"+"h1>"+Text+"<a onclick=\"expandPanel\">[+]</a></h1>"));    
        Panel panel=new Panel();
        // add controls in collapsable panel to panel here
        Controls.Add(panel);
    }
    

    翻译为:

    <div id="ctl00_etc_myCollapsiblePanel">
       <h1>Panel title <a onclick="expandPanel">[+]</a></h1>
       <div id="childPanel" style="display:none">
          <label id="ctl_00_etc">Test Label</label>
          <input ... />
       </asp:Panel>
    </div>
    

    还有一些jQuery(或类似的)附加到&lt;a&gt;:

    function expandPanel() {
        $('<%=childPanel.ClientID %>').css('display','block');
    }
    

    当然,所有这些都是伪代码。

    【讨论】:

      猜你喜欢
      • 2013-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-15
      相关资源
      最近更新 更多