asp.net - 自定义 ASP.net 服务器控件 - 渲染

标签 asp.net controls

我目前正在 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);
}

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

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

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

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

感谢您的帮助!

最佳答案

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

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]);

关于asp.net - 自定义 ASP.net 服务器控件 - 渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/668936/

相关文章:

ASP.NET 正则表达式验证器无法在 Internet Explorer 7 上运行

java - 如何在 Windows (7) 上更改 Java 运行时版本?

c# - 是否可以将两个源属性绑定(bind)到一个控件属性?

python - 用于开发 Python 和 Google App Engine 的资源

c# - 为输入创建非矩形控件

ASP.NET MVC - 母版页的代码隐藏

c# - 如何使 javascript 文件在从母版页继承的任何页面上工作?

c# - 使用 C# 访问另一个域中的一个域类文件

ios - swift - 将 subview 添加到段控件会导致无效行为

php - ASP.Net MVC或Zend框架。您的意见是什么?