私は非常に異常な状況に対処しているため、いくつかの回答を待つ努力をしました。
次のドキュメントに基づいて、いくつかのコントロールを再生成しようとしています。
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++;
}