我想在页面上放一个按钮,点击一下按钮可以生成一个Label和一个Textbox,再点击按钮可以再生成一个Label和一个Textbox。可是,我的程序在点击按钮之后可以生成一个Label和一个Textbox,再点击会替换掉原先生成的,怎么办?我的代码如下:
页面:
<asp:textbox id="txt_count" Runat="server"></asp:textbox>
<asp:panel id="pan_OtherHost" Runat="server"></asp:panel>
<asp:button id="Button1" runat="server" Text="增加"></asp:button>后台:
txt_count的初始值为1;
private void Button1_Click(object sender, System.EventArgs e)
{
i=Convert.ToInt32(this.txt_count.Text);
System.Web.UI.WebControls.Label lab1=new Label();
lab1.ID="lab_Name"+this.txt_count.Text;
lab1.Text="第"+this.txt_count.Text+"个文本框";
System.Web.UI.WebControls.TextBox txt1=new TextBox();
txt1.ID="txt_Name"+this.txt_count.Text;
this.pan_OtherHost.Controls.AddAt(this.pan_OtherHost.Controls.Count,lab1);
this.pan_OtherHost.Controls.AddAt(this.pan_OtherHost.Controls.Count,txt1);
i++;
this.txt_count.Text=i.ToString();
}
我希望的是点击一次生成一个,再点击再生成一个,点击N次生成N个,但是我的这个程序怎么点都生成一个。怎么办?
页面:
<asp:textbox id="txt_count" Runat="server"></asp:textbox>
<asp:panel id="pan_OtherHost" Runat="server"></asp:panel>
<asp:button id="Button1" runat="server" Text="增加"></asp:button>后台:
txt_count的初始值为1;
private void Button1_Click(object sender, System.EventArgs e)
{
i=Convert.ToInt32(this.txt_count.Text);
System.Web.UI.WebControls.Label lab1=new Label();
lab1.ID="lab_Name"+this.txt_count.Text;
lab1.Text="第"+this.txt_count.Text+"个文本框";
System.Web.UI.WebControls.TextBox txt1=new TextBox();
txt1.ID="txt_Name"+this.txt_count.Text;
this.pan_OtherHost.Controls.AddAt(this.pan_OtherHost.Controls.Count,lab1);
this.pan_OtherHost.Controls.AddAt(this.pan_OtherHost.Controls.Count,txt1);
i++;
this.txt_count.Text=i.ToString();
}
我希望的是点击一次生成一个,再点击再生成一个,点击N次生成N个,但是我的这个程序怎么点都生成一个。怎么办?
解决方案 »
- 求一个存储过程。以及asp.net前台如何获取返回值
- 页面值传递
- linq数据传递问题
- 在中文windows 下开发的WEB程序,拿到英文WINDOWS下服务器上, 能运行吗? 只要客户端用中文浏览器就行了吗?
- 请问XML + SQL的项目设计方案具体是怎么样的呢???????????????????????????????????????????????????????
- 在asp.net中把变量值传到javascript中
- Web服务怎样控制返回值的XML格式...
- datagrid中的Findcontrol方法的疑问?
- [50分]如何判断数据库中是否有该条记录?
- 请问SqlHelperParameterCache 用来干什么?
- submit问题,高手来看看
- oracle的时间字段插入问题
然后每点击一次new一个,再load到页面
以前我就发现过这样的问题,当时好像是搞一个自定义控件( 继承自panel控件 ) ,然后override里面的OnInit事件.好像原因就是panel.controls.Add()出来的动态控件,是在页面呈现之后.
overriede OnInit的目的,就是要先加载这些控件.
创建应该是小问题.自己多想想,应该很容易搞定.
Good luck.
解决办法是:
1、在Button1_Click中,当创建新的按钮和Label后,立即把该按钮和label的名称(或其他自定义的标志信息)保存到ViewState
2、在页面load中,判断ViewState中的内容,并据此还原创建上次创建过的按钮和lable说白了就是自己来实现状态保持。
下面是伪代码:
page_load:
if viewstate["old"] !=Null then
string TxtBoxID = viewstate["old"];
TextBox TxtOld = new TextBox();
TextBox.id =btnID;
end ifButton1_Click:
TextBox Txt1 = new TextBox();
Txt1.id ="abc";
viewstate["old"]=Txt1.id;
没看明白,能详细点吗?btnID是那来的?
2. 可以移动每一行的位置。这两个功能可以更好地说明这类程序的编写所涉及到的问题。顺便说一下,真正的动态装载控件的程序不太可能在OnInit的时候创建所谓动态控件。因为“动态”功能,所以装载时程序要读取ViewState来决定到底如何装载,同时控件自己也要自动地读取ViewState。如果在一个根本读不到页面状态的OnInit阶段去装载动态控件,感觉就是盲人摸象一样不可能写出完整功能功能的动态装载控件的程序(肯定会抱怨无法获得状态)。下面是demo,一共有三个文件,创建以下三个文件就可以直接运行测试:1. 在App_Code下的文件 IMyLine.csusing System;public interface IMyLine
{
int 行号 { get; set; }
string Text { get; set; } event EventHandler<EventArgs> Delete;
event EventHandler<EventArgs> Move;
}
2. 如1楼所说的封装组件的文件 MyLine.ascx<%@ Control Language="C#" %>
<%@ Implements Interface="IMyLine" %><script runat="server">
public event EventHandler<EventArgs> Delete;
public event EventHandler<EventArgs> Move; public int 行号
{
get
{
object x = ViewState["l_no"];
return x == null ? 1 : (int)x;
}
set
{
ViewState["l_no"] = value;
EnsureChildControls();
this.Label1.DataBind();
}
} public string Text
{
get
{
EnsureChildControls();
return this.TextBox1.Text;
}
set
{
EnsureChildControls();
this.TextBox1.Text = value;
}
} protected void Button1_Click(object sender, EventArgs e)
{
if (this.Delete != null)
this.Delete(this, EventArgs.Empty);
} protected void Button2_Click(object sender, EventArgs e)
{
if (this.Move != null)
this.Move(this, EventArgs.Empty);
}
</script><asp:Label ID="Label1" runat="server" Text='<%# string.Format("第{0}个文本框",this.行号) %>' />
<asp:TextBox ID="TextBox1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="删除本行" OnClick="Button1_Click" />
<asp:Button ID="Button2" runat="server" Text="移动位置" OnClick="Button2_Click" />
<hr />
3. 测试主页 default.aspx <%@ Page Language="C#" %><%@ Import Namespace="System.Collections.Generic" %><script runat="server"> protected void Button1_Click(object sender, EventArgs e)
{
最大行序号++;
string id = "line" + 最大行序号.ToString();
IMyLine uc = CreateALine(id);
uc.Text = this.TextBox1.Text;
uc.行号 = 最大行序号;
未删除行的id.Add(id);
this.TextBox1.Text = string.Empty;
this.TextBox1.Focus();
} protected void Page_Load(object sender, EventArgs e)
{
foreach (string id in 未删除行的id)
{
IMyLine uc = CreateALine(id);
uc.Delete += new EventHandler<EventArgs>(uc_Delete);
uc.Move += new EventHandler<EventArgs>(uc_Move);
}
} void uc_Move(object sender, EventArgs e)
{
Control uc = (Control)sender;
PlaceHolder1.Controls.Remove(uc);
PlaceHolder1.Controls.AddAt(0, uc);
未删除行的id.Remove(uc.ID);
未删除行的id.Insert(0, uc.ID);
} void uc_Delete(object sender, EventArgs e)
{
Control uc = (Control)sender;
未删除行的id.Remove(uc.ID);
this.PlaceHolder1.Controls.Remove(uc);
} private IMyLine CreateALine(string id)
{
Control uc = this.LoadControl("MyLine.ascx");
uc.ID = id;
PlaceHolder1.Controls.Add(uc);
return (IMyLine)uc;
} private int 最大行序号
{
get
{
object x = ViewState["最大行序号"];
return x == null ? 0 : (int)x;
}
set
{
ViewState["最大行序号"] = value;
}
} private List<string> 未删除行的id
{
get
{
object x = ViewState["行id集合"];
if (x == null)
{
x = new List<string>();
ViewState["行id集合"] = x;
}
return (List<string>)x;
}
}
</script><html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
<hr />
文本框的初始值:<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="添加到最后" OnClientClick="return abc();"
OnClick="Button1_Click" />
<br />
<br />
<asp:Button ID="Button2" runat="server" Text="测试页面回发(例如您可以先修改文本框中的内容)" />
</form>
</body>
</html>
实际上,这中程序更加适合创建一个数据集合(然后放到ViewState或者数据库中持久化),然后仅仅使用一个简单的DataList甚至GridView绑定一下就可以了,要比这里的程序简单许多倍。要多用高级的控件,少写低级的代码。只是为了演示如何设计动态装载的程序设计,我才这样设计。