1

私は非常に異常な状況に対処しているため、いくつかの回答を待つ努力をしました。

次のドキュメントに基づいて、いくつかのコントロールを再生成しようとしています。

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

このアプローチは TextBox コントロールで機能しますが、Label、Literal、UploadFile、または私が認識していないその他のコントロールには応答しないようです。

セキュリティ上の理由により、これが UploadFile では機能しないことは理解していますが、他の非 TextBox コントロールでは機能しないのはなぜですか?

上記の記事は、コントロールの ID を維持する場合、ポストバック後にそれらを保持できることを示唆していますが、次の実装では、このソリューションに応答する TextBox のみを取得します。この状況での「ラベル」および「リテラル」コントロールは、PostBack の後で失われます。これは、レシピを 1 行ずつほぼ追っていることを考えると、望ましくありません。

誰かが次の実装を見て、どこが間違っているか、または概念全体が間違っているかどうかを確認できますか?

これは、生成されたコントロール セットの数を追跡するためのカウンターです。

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

これは、最初のページ読み込み時に DB から前のスライドを取得し、ポストバック時に同じページを再生成する Page_Load イベントです。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);
    }
}

次のコードは、新しいコントロール セットをプレースホルダーの "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++;
}
4

1 に答える 1

1

このように言って申し訳ありませんが、あなたが頼っている記事は間違っています。

動的に作成されたコントロールは、ViewState の前に存在するように、Page_Init で作成する必要があります。また、PostBack かどうかに関係なく、Page が初期化されるたびに動的コントロールを再作成する必要があります。

ViewState/PostBack はコントロールを「保持」せず、そのようなコントロールの状態のみを保持します。

この記事をお読みください: ASP.NET ページのライフ サイクルの概要

于 2013-07-09T09:33:57.587 に答える