回发失败后保留Label和Literal控件

本文关键字:Literal 控件 Label 保留 失败 | 更新日期: 2023-09-27 18:21:33

我正在处理一个非常不寻常的情况,通过这个情况,我努力寻找一些答案。

我正在尝试根据以下文档重新生成一些控件,

http://www.codeproject.com/Articles/3684/Retaining-State-for-Dynamically-Created-Controls-i

这种方法可以使用TextBox控件,但似乎不会对Label、Literal、UploadFile或其他我不知道的控件做出响应。

由于安全原因,我确实理解这对UploadFile不起作用,但为什么对其他非TextBox控件不起作用呢?

上面的文章建议,如果我们维护控件的ID,我们可以在post-back后保留它们,但在下面的实现中,我只得到响应此解决方案的TextBox。在这种情况下,"Label"answers"Literal"控件在PostBack之后丢失,这是不可取的,因为我几乎是一行接一行地遵循配方。

请有人看看下面的实现,看看我哪里出了问题,或者我是否在某种程度上误解了整个概念?

这是一个计数器,用于跟踪生成的控制集的数量,

protected int NumberOfControls
{
    get { return (int)ViewState["NumControls"]; }
    set { ViewState["NumControls"] = value; }
}

这是Page_Load事件,它在初始页面加载时从DB中获取以前的幻灯片,并在Postback上重新生成相同的页面。AddSlide是一个"占位符"控件,我在其中发布其他控件。

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        this.NumberOfControls = PopulateCarouselSettingFields(AddSlides);
    }
    else
    {
        this.GenerateControls();
    }
}

这是"PopulateCaroouselSettingsFields"的定义。

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

下面的代码将一组新的控件添加到占位符"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++;
}

回发失败后保留Label和Literal控件

很抱歉这样说,但您所依赖的文章做得不对。

动态创建的控件必须在Page_Init中创建,以便它们存在于任何ViewState内容之前。此外,每次初始化页面时,无论是否PostBack,都必须重新创建动态控件。

ViewState/PostBack不"保留"控件,只保留此类控件的状态。

请阅读这篇文章:ASP.NET页面生命周期概述