我正处理一个非常不寻常的情况,通过这种情况让我努力寻求答案。
我正在尝试根据以下文档重新生成一些控件,
http://www.codeproject.com/Articles/3684/Retaining-State-for-Dynamically-Created-Controls-i
这种方法适用于TextBox控件,但似乎没有响应Label,Literal,UploadFile或其他我不知道的控件。
由于安全原因,我确实理解这不适用于UploadFile,但为什么不能用于其他非TextBox控件?
上面的文章建议如果我们维护一个控件的ID,我们可以在回发后保留它们,但在下面的实现中我只得到TextBox响应这个解决方案。在PostBack之后,这种情况下的“标签”和“文字”控件都会丢失,这是不可取的,因为我几乎都是逐行遵循配方。
有人可以看看下面的实现,看看我哪里出错了,或者我是否在某种程度上弄错了整个概念?
这是一个跟踪生成的控制集数量的计数器,
protected int NumberOfControls
{
get { return (int)ViewState["NumControls"]; }
set { ViewState["NumControls"] = value; }
}
这是Page_Load事件,它在初始页面加载时从数据库中提取以前的幻灯片,并在Postback上重新生成相同的页面。 AddSlide是一个“占位符”控件,我将其他控件发布到。
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
this.NumberOfControls = PopulateCarouselSettingFields(AddSlides);
}
else
{
this.GenerateControls();
}
}
这是“PopulateCarouselSettingsFields”的定义。
public static int PopulateCarouselSettingFields(PlaceHolder _AddSlides)
{
string result = string.Empty;
int counter = 0;
string CS = ConfigurationManager.ConnectionStrings["someconn"].ConnectionString;
using (SqlConnection conn = new SqlConnection(CS))
{
SqlCommand SqlCmd = new SqlCommand();
conn.Open();
SqlCmd.Connection = conn;
SqlCmd.CommandType = CommandType.StoredProcedure;
SqlCmd.CommandText = "storedprocedure";
SqlDataReader dReader;
dReader = SqlCmd.ExecuteReader();
while (dReader.Read())
{
Literal lit1 = new Literal();
lit1.ID = "Lit1_" + counter;
lit1.Text = "<div class=\"controls controls-row\"><div class=\"span3\">";
_AddSlides.Controls.Add(lit1);
Label CarouselTextLabel = new Label();
CarouselTextLabel.ID = "CarouselTextLabel" + counter;
CarouselTextLabel.Text = "Carousel Text";
CarouselTextLabel.Font.Bold = true;
CarouselTextLabel.CssClass = "control-label";
_AddSlides.Controls.Add(CarouselTextLabel);
TextBox CarouselText = new TextBox();
CarouselText.ID = "CarouselText" + counter;
CarouselText.TextMode = TextBoxMode.MultiLine;
CarouselText.Height = 50;
CarouselText.Text = dReader["CarouselText"].ToString();
_AddSlides.Controls.Add(CarouselText);
Literal Lit2 = new Literal();
Lit5.ID = "Lit2_" + counter;
Lit5.Text = "</div></div></div><br />";
_AddSlides.Controls.Add(Lit2);
counter++;
}
}
return counter;
}
这应该是在从Page_Load事件调用的PostBack上使用它们的ID重新生成或重新声明所有控件。
protected void GenerateControls()
{
int count = this.NumberOfControls;
for (int i = 0; i < count; i++)
{
Literal lit1 = new Literal();
lit1.ID = "Lit1_" + i.ToString();
AddSlides.Controls.Add(lit1);
Label CarouselTextLabel = new Label();
CarouselTextLabel.ID = "CarouselTextLabel" + i.ToString();
AddSlides.Controls.Add(CarouselTextLabel);
TextBox CarouselText = new TextBox();
CarouselText.ID = "CarouselText" + i.ToString();
AddSlides.Controls.Add(CarouselText);
Literal Lit2 = new Literal();
Lit2.ID = "Lit2_" + i.ToString();
AddSlides.Controls.Add(Lit2);
}
}
以下代码段向Placeholder“AddSlides”容器添加了一组新控件。
protected void AddMoreSlidesToCarousel(object sender, EventArgs e)
{
Literal lit1 = new Literal();
lit1.ID = "Lit1_" + NumberOfControls.ToString();
lit1.Text = "<div class=\"controls controls-row\"><div class=\"span3\">";
AddSlides.Controls.Add(lit1);
Label CarouselTextLabel = new Label();
CarouselTextLabel.ID = "CarouselTextLabel" + NumberOfControls.ToString();
CarouselTextLabel.Text = "Carousel Text";
CarouselTextLabel.Font.Bold = true;
CarouselTextLabel.CssClass = "control-label";
AddSlides.Controls.Add(CarouselTextLabel);
TextBox CarouselText = new TextBox();
CarouselText.ID = "CarouselText" + NumberOfControls.ToString();
CarouselText.TextMode = TextBoxMode.MultiLine;
CarouselText.Height = 50;
AddSlides.Controls.Add(CarouselText);
Literal Lit2 = new Literal();
Lit2.ID = "Lit2_" + NumberOfControls.ToString();
Lit2.Text = "</div></div></div><br />";
AddSlides.Controls.Add(Lit2);
this.NumberOfControls++;
}
答案 0 :(得分:1)
我很抱歉这样说,但你所依赖的文章做错了。
动态创建的控件必须在Page_Init中创建,以便它们存在于任何ViewState之前。此外,每次初始化Page,PostBack时都必须重新创建动态控件。
ViewState / PostBack不会“保留”控件,只会控制此类控件的状态。
请阅读这篇文章:ASP.NET Page Life Cycle Overview