Rekonštrukcia ViewState dynamicky pridaných kontrolov jradoslav - 27. 12. 2008 20:20 - 10873 views Rekonštrukcia ViewState dynamicky pridaných kontrolov. Pred nedávnom som riešil problém ako rekonštruovať viewstate v postbacku dynamicky vytvorených kontrolov ako je napr Label, alebo iný control (napr. vlastný). Dynamicky pridávané servrové kontroly majú široké využitie, napr. renderovanie šablón, ktoré obsahujú istú servrovskú funkčnosť (bežné formuláre). A zároveň chceme aby zmeny v šablónach boli vykonávané za behu aplikácie, čiže nieje potrebná kompilácia aspx stránok. Toto je riešenie ktoré nám fungovať bude iba ak nieje postovaný formulár, to znamená že pridaný Label sa nám v postbacku stratí. protected override void OnInit(EventArgs e) ...{ base.OnInit(e); if (!IsPostBack) ...{ Label newLabel = new Label(); this.Controls.Add(newLabel); newLabel.Text = retrieveTextFromDatabase(); } } Chceme predsa, aby sa v postbacku Label zobrazil správne bez dotazovania sa na databázu. Tu je riešenie: protected override void OnInit(EventArgs e) ...{ base.OnInit(e); if (!IsPostBack) ...{ Label newLabel = new Label(); this.Controls.Add(newLabel); newLabel.Text = retrieveTextFromDatabase(); } else ...{ Label newLabel = new Label(); this.Controls.Add(newLabel); } } Podstata je v tom že poradie pridávaných dynamických kontrolov musí byť v PostBacku rovnaké ako v Not PostBacku Dôležitá zásada je poradie inicializácie premennej Text. táto inicializácia sa musí vykonať až po pridaní kontrolu do rodiča. Jedine vtedy sa zosynchronizujú indexy Viewstatu a prevedie sa správna inicializácia kontrolu. Volaná metóda 'this.Controls.Add(newLabel);' musí byť pred 'newLabel.Text = retrieveTextFromDatabase(); ' Premenná Text musí byť uložená vo ViewState Ak používate vlastný kontrol ako je to v tomto pripade, je dôležité aby premenná InnerHTML bola ukladaná vo ViewState so svojím Indexom. public class RawHtmlContainer :Control ...{ public string InnerHTML ...{ get ...{ return ViewState["InnerHTML"] == null ? String.Empty : ViewState["InnerHTML"] as String; } set ...{ ViewState["InnerHTML"] = value; } } protected override void Render(HtmlTextWriter writer) ...{ writer.Write(InnerHTML); } } Príklad inicializácie: protected override void OnInit(EventArgs e) ...{ base.OnInit(e); if (!IsPostBack) ...{ Label newLabel = new Label(); RawHtmlContainer container = new RawHtmlContainer(); this.Controls.Add(newLabel); this.Controls.Add(container); container.InnerHTML = retrieveHtmlFromDatabase(); newLabel.Text = retrieveTextFromDatabase(); } else ...{ Label newLabel = new Label(); RawHtmlContainer container = new RawHtmlContainer(); this.Controls.Add(newLabel); this.Controls.Add(container); } }