这就是事情,我现在有一个我想要的工作原型,它似乎完全适合我想做的事情。话虽如此,这可能不是最好的方法。最好的是,我的意思是程序简单性,但我实际编码它。无论如何,首先描述页面应该做什么:
1)页面包含一个文本框(Textbox1),一个占位符(Placeholder1)和一个按钮(Button1)
这个代码很简单:
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
<hr />
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
<hr />
2)用户可以在文本框中输入一个数字(例如99),然后单击按钮。然后,占位符将填充99个文本框,其中包含&#34; save&#34;每个旁边的按钮 3)用户可以编辑任何文本框并单击它旁边的保存,然后按钮点击事件调用的功能需要能够访问A)文本框当前值,B)文本框旧值,C)任何数量的元数据
这是我目前的工作解决方案:
protected void Page_Load(object sender, EventArgs e)
{
createStuff(false);
}
void test(object sender, EventArgs e)
{
Button btn = (Button)sender;
Response.Write(btn.ID + "Clicked" + "<br />");
Response.Write("Metadata: " + Session[btn.ID + "a"] + "<br />");
Response.Write("Old text: " + Session[btn.ID + "b"] + "<br />");
TextBox txtBlah = (TextBox)PlaceHolder1.FindControl("txt"+btn.ID);
Response.Write("New text: " + txtBlah.Text + "<br />");
Session[btn.ID + "b"] = txtBlah.Text;
}
protected void Button1_Click(object sender, EventArgs e)
{
Session["num"] = TextBox1.Text;
createStuff(true);
}
private void createStuff(bool btnClick)
{
PlaceHolder1.Controls.Clear();
int numBtn = Convert.ToInt32(Session["num"]);
for (int i = 0; i < numBtn; i++)
{
TextBox txtTemp = new TextBox();
txtTemp.Text = "old" + i;
txtTemp.ID = "txt" + "btn" + i;
PlaceHolder1.Controls.Add(txtTemp);
Button btn = new Button();
btn.Text = "btn" + i;
btn.ID = "btn" + i;
btn.Click += new EventHandler(test);
PlaceHolder1.Controls.Add(btn);
Session[btn.ID + "a"] = "meta" + i;
if (btnClick)
{
Session[btn.ID + "b"] = txtTemp.Text;
}
PlaceHolder1.Controls.Add(new LiteralControl("<br />"));
}
}
我认为这实际上相当不错,我对它非常满意。但是,我知道我必须做一些改进,因为关于ASP回发系统和对象模型或其他所谓的内容的一些教程现在甚至让我感到困惑。
任何帮助,甚至只是想法都有帮助,谢谢。
答案 0 :(得分:2)
我能看到的唯一重大改进是:使用UserControl,将TextBox
和Button
放在里面,添加属性(如OldValue / NewValue,存储在ViewState / TextBox中)和使用LoadControl创建实例后,将这些UserControl添加到PlaceHolder
。
“MetaData”也应该作为属性存储在UserControl中。您应该使用事件在UserControl和Page之间进行通信(例如TextSaved
)。
您可以在ViewState中存储已创建控件的数量,而不是Session。这是您需要存储在页面中的唯一内容。将UserControl的索引附加到它的ID。
Web用户控件的一般优点:
Web用户控件的最大优点是可以将它们创建为站点模板并在整个站点中使用。例如,可以使它们包含站点的Menu / Link结构,并且可以在所有其他aspx页面上使用。
这意味着以下内容:
.ascx文件既可以用作普通HTML的简单替代品,也可以用来响应事件:这意味着甚至可以针对它们创建自定义代码并将其放在文件后面的代码中
UserControls封装复杂性总是有益于增加
......并减少出错的可能性
阅读this SO-answer了解更多示例。
答案 1 :(得分:0)
好吧我不知道如果这是我回发我最新代码的正确位置,但我猜它会算作“答案”。我也非常感谢你的回答,他们非常乐于助人。有点神秘但有五十页的教程等等,是的,你的推荐很精彩,所以谢谢你,勇敢。无论如何,我最新的一个与我认为你推荐的新增功能完美配合。如果你想要达到巅峰,看看你是否仍然做了一些不同的事情,或者更容易,请随时告诉我
首先我的用户控件“MyControl”
ASCX:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MyControl.ascx.cs" Inherits="DBtest.MyControl" %>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
<br />
ascx.cs:
//private String _oldText;
private String _metaData;
public String OldText
{
get
{
//return _oldText;
return (String)ViewState["OldText"];
}
set
{
//_oldText = value;
ViewState["OldText"] = value;
}
}
public String MetaData
{
get
{
return _metaData;
}
set
{
_metaData = value;
}
}
public String NewText
{
get
{
return TextBox1.Text;
}
set
{
TextBox1.Text = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
Response.Write("My ID: " + this.ID + "<br />");
Response.Write("My Metadata: " + _metaData + "<br />");
Response.Write("My Old Text: " + ViewState["OldText"] + "<br />");
Response.Write("My New Text: " + TextBox1.Text + "<br />");
ViewState["OldText"] = TextBox1.Text;
}
然后我的页面,aspx:
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="TESTdynamicButton3.aspx.cs" Inherits="DBtest.TESTdynamicButton3" %>
<%@ Register TagPrefix="uc" TagName="Spinner" Src="MyControl.ascx" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
<hr />
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
<hr />
</asp:Content>
aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
createStuff(false);
}
protected void Button1_Click(object sender, EventArgs e)
{
ViewState["num"] = TextBox1.Text;
createStuff(true);
}
private void createStuff(bool btnClick)
{
PlaceHolder1.Controls.Clear();
int numBtn = Convert.ToInt32(ViewState["num"]);
for (int i = 0; i < numBtn; i++)
{
MyControl temp2 = LoadControl("MyControl.ascx") as MyControl;
temp2.ID = "uc" + i;
temp2.MetaData = "meta" + i;
//not sure why this DOES work, i would think it is overwritten each page load >.<
temp2.OldText = "old" + i;
if (btnClick)
{
temp2.NewText = "old" + i;
//not sure why this doesnt work below this line
//temp2.OldText = "old" + i;
}
//also not sure why this won't work
//temp2.OldText = temp2.NewText;
PlaceHolder1.Controls.Add(temp2);
}
}
我也有几个内容,我不确定它是否完全合理为什么或做或不使用这些行来让“旧文本”视图状态最初正确填充。我原以为我需要进行按钮检查,并且只设置第一次使用它的视图状态。我也不确定我理解为什么当我尝试将createStuff()函数移动到OnInit或者初始化函数被覆盖时它无法工作..
谢谢!
利奥