如何动态添加控件到指定位置?

sbvoagnn 2008-10-05 05:23:04
我现在想在Panel里动态添加一个Button到最底部,如下:

<asp:Panel ID="Panel1" runat="server">
这里有内容
</asp:Panel>


Button _button = new Button();
Panel1.Controls.Add(_button);


但是,现在我想把button动态添加在"这里有内容"下面,也就是在</asp:Panel>前面,请问怎么实现?
...全文
184 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
sbvoagnn 2008-10-06
  • 打赏
  • 举报
回复
其实我就是想在设计时随意布局和修改内容,所以继承了Panel类,

用了种笨方法把问题解决了。

protected override void Render(HtmlTextWriter writer)
{
Controls.Remove(_button);//先将button移出Controls集,这样输出就不会显示此button
RenderContents(writer);//显示Panel内的内容
writer.RenderBeginTag(HtmlTextWriterTag.Div);
this.Controls.Add(_button);//必须再将button添加到Controls集,这样能才捕获到onclick的事件
_button.RenderControl(writer);//显示button
writer.RenderEndTag();
}
  • 打赏
  • 举报
回复
嗯,我没有看懂你

public override ControlCollection Controls
{
get
{
EnsureChildControls();
return base.Controls;
}
}

是个什么意思。对于这个程序的逻辑,不要执行Control.Clear()看上去比较顺。重写Controls则比较诡异。
  • 打赏
  • 举报
回复
如果你不是为了在设计时可以增加一些内容,这个控件不要从Panel继承,从WebControl继承就可以了。
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
哦,原来你的“这里有内容”不是指设计时的代码啊。

那你这两行

this.Controls.Add(_button);
this.Controls.Add(_label);

掉一个次序啊。
sbvoagnn 2008-10-05
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 sp1234 的回复:]
我看到你的代码中有

protected override void CreateChildControls()
{
Controls.Clear();

这肯定会删除原来在设计页面上定义的。没有仔细看你的代码逻辑,不去Clear会有什么问题?
[/Quote]
问题可能不在clear,现在问题是这样:
1、

<cc1:FlowContral ID="FlowContral1" runat="server" Text="点我啊">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</cc1:FlowContral>

得到的HTML代码如下:
<div id="FlowContral1">
<input type="submit" name="btn" value="点我啊" id="btn" /><span id="lab"></span>
<input name="TextBox1" type="text" id="TextBox1" />
</div>

而我希望的HTML代码如下:
<div id="FlowContral1">
<input name="TextBox1" type="text" id="TextBox1" />
<input type="submit" name="btn" value="点我啊" id="btn" /><span id="lab"></span>

</div>

  • 打赏
  • 举报
回复
我看到你的代码中有

protected override void CreateChildControls()
{
Controls.Clear();

这肯定会删除原来在设计页面上定义的。没有仔细看你的代码逻辑,不去Clear会有什么问题?
  • 打赏
  • 举报
回复
当你写 Panel1.Controls.Add(_button); 的时候,其实很大程度上已经是放在“下面”了。

我理解你的意思是要保证在浏览器上解析时处于“正下方”。

是这个意思吗?


另外,你不能为 FlowContral 里边的一个子控件“写死”ID!如果页面上有多个 FlowContral 实例,或者有一个控件的 ID 也是 lab 就麻烦了。解决的办法,是将 FlowContral 定义为:

[DefaultProperty("Text")]
[ToolboxData("<{0}:ServerControl1 runat=server></{0}:ServerControl1>")]
public class FlowContral : Panel,INamingContainer
{
sbvoagnn 2008-10-05
  • 打赏
  • 举报
回复
非常感谢sp1234的回复,看到了受益匪浅。实际上我是想开发一个服务器控件,该控件继承Panel类,


<cc1:FlowContral ID="FlowContral1" runat="server" Text="立即提交" OnButtonClick="SaveFlow">
这里有内容
</cc1:FlowContral>

我是想将Botton添加到"这里有内容"下面,不知道怎么实现?

服务器控件代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace test
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:ServerControl1 runat=server></{0}:ServerControl1>")]
public class FlowContral : Panel
{
//声明变量
private Button _button;
private static readonly object EventButtonClick = new object();
private Style _buttonStyle;
private Label _label;

//定义属性Text,用于指定按钮上的文字
[
Bindable(true),
Category("Appearance"),
DefaultValue(""),
Description("获取或设置显示显示在按钮上的文字")
]
public string Text
{
get
{
EnsureChildControls();
return _button.Text;
}
set
{
EnsureChildControls();
_button.Text = value;
}
}

//定义ButtonStyle属性
[
Category("Style"),
Description("设置Button的样式属性"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
]
public virtual Style ButtonStyle
{
get
{
if (_buttonStyle == null)
{
_buttonStyle = new Style();
if (IsTrackingViewState)
{
((IStateManager)_buttonStyle).TrackViewState();
}
}
return _buttonStyle;
}
}

//重写Controls属性
public override ControlCollection Controls
{
get
{
EnsureChildControls();
return base.Controls;
}
}
//重写CreateChildControls方法,将子控件添加到复合控件中
protected override void CreateChildControls()
{
Controls.Clear();
_button = new Button();
_label = new Label();
_label.ID = "lab";
_button.ID = "btn";
_button.CommandName = "ButtonClick";
this.Controls.Add(_button);
this.Controls.Add(_label);
}


public event EventHandler ButtonClick
{
add
{
Events.AddHandler(EventButtonClick, value);
}
remove
{
Events.RemoveHandler(EventButtonClick, value);
}
}

protected virtual void OnButtonClick(EventArgs e)
{
EventHandler buttonClickHandler = (EventHandler)Events[EventButtonClick];
if (buttonClickHandler != null)
{
buttonClickHandler(this, e);
}
}

protected override bool OnBubbleEvent(object sender, EventArgs e)
{
bool handled = false;
if (e is CommandEventArgs)
{
CommandEventArgs ce = (CommandEventArgs)e;
if (ce.CommandName == "ButtonClick")
{
OnButtonClick(EventArgs.Empty);
handled = true;
}
}
return handled;
}


}
}

  • 打赏
  • 举报
回复
[Quote=引用 3 楼 sp1234 的回复:]
如果需要比较准确地动态排版,应该使用 <table>。例如:
HTML code
<asp:Panel ID="Panel1" runat="server">
这里有内容<br />
这里有内容<br />
<table border=0 cellspacing=0 cellpadding=0>
<tr>
<td>这里有内容</td>
<td><asp:PlaceHolder ID="place1" runat="server" /></td>
</tr>
</table>
</asp:Panel>
[/Quote]

少写了一个换行,应该为:
<asp:Panel ID="Panel1" runat="server">
这里有内容<br />
这里有内容<br />
<table border=0 cellspacing=0 cellpadding=0>
<tr>
<td>这里有内容</td>
</tr>
<tr>
<td><asp:PlaceHolder ID="place1" runat="server" /></td>
</tr>
</table>
</asp:Panel>
jcrjia 2008-10-05
  • 打赏
  • 举报
回复
Button _button = new Button();
Panel1.Controls.AddAt(Panel1.Controls.Count,_button);
  • 打赏
  • 举报
回复
如果需要比较准确地动态排版,应该使用 <table>。例如:

<asp:Panel ID="Panel1" runat="server">
这里有内容<br />
这里有内容<br />
<table border=0 cellspacing=0 cellpadding=0>
<tr>
<td>这里有内容</td>
<td><asp:PlaceHolder ID="place1" runat="server" /></td>
</tr>
</table>
</asp:Panel>
  • 打赏
  • 举报
回复

<asp:Panel ID="Panel1" runat="server">
这里有内容<br />
</asp:Panel>
skyering 2008-10-05
  • 打赏
  • 举报
回复
文字后面在放个panel

62,025

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧