2011-01-28 16 views
5

Próbuję utworzyć złożony formant ASP.NET, który pozwala budować edytowalną kolekcję kontrolną.Liczba dynamicznych elementów sterujących ASP.NET (tworzenie formantów w trakcie pracy)

Mój problem polega na tym, że po naciśnięciu przycisku dodawania lub odświeżania strony (który nie powoduje niczego innego niż odświeżenie formularza) wszelkie wartości wprowadzone w polach tekstowych zostaną utracone.

Nie mogę uruchomić go, gdy liczba elementów sterujących zmienia się między wysyłkami zwrotnymi. Muszę zasadniczo być w stanie odtworzyć drzewo kontrolne w dwóch różnych czasach w cyklu kontrolnym w zależności od właściwości stanu widoku ControlCount.

Test ten może być stosowany do odtworzenia problemu:

public class AddManyControl : CompositeControl 
{ 
    protected override void OnLoad(EventArgs e) 
    { 
     base.OnLoad(e); 
     EnsureChildControls(); 
    } 

    protected override void CreateChildControls() 
    { 
     var count = ViewState["ControlCount"] as int? ?? 0; 

     for (int i = 0; i < count; i++) 
     { 
      var div = new HtmlGenericControl("div"); 
      var textBox = new TextBox(); 
      textBox.ID = "tb" + i; 
      div.Controls.Add(textBox); 
      Controls.Add(div); 
     } 

     ViewState["ControlCount"] = count; 

     var btnAdd = new Button(); 
     btnAdd.ID = "Add"; 
     btnAdd.Text = "Add text box"; 
     btnAdd.Click += new EventHandler(btnAdd_Click); 
     Controls.Add(btnAdd); 

     var btnPostBack = new Button(); 
     btnPostBack.ID = "PostBack"; 
     btnPostBack.Text = "Do PostBack"; 
     Controls.Add(btnPostBack); 
    } 

    void btnAdd_Click(object sender, EventArgs e) 
    { 
     ViewState["ControlCount"] = (int)ViewState["ControlCount"] + 1; 
    } 

    protected override void OnPreRender(EventArgs e) 
    { 
     base.OnPreRender(e); 
     // If I remove this RecreateChildControls call 
     // the collection lags behind each postback 
     // because the count is incremented in the btnAdd_Click event handler 
     // however, the values are not lost between postbacks 
     RecreateChildControls(); 
    } 
} 

Odpowiedz

5

Jeśli chcesz grać z niestandardowymi kontrolkami ASP.NET, musisz grać według jego reguły i wybredności! Kiedy zaczynasz grać z OnPreRender w niestandardowym sterowaniu, wiesz, że jesteś w złym torze w 90% przypadków.

Ogólnie rzecz biorąc, najlepszym sposobem korzystania z ViewState jest deklarowanie właściwości kopii zapasowej przez nią, podobnie jak standardowe formanty ASP.NET ((.NET Reflector jest moim nauczycielem od lat!). W ten sposób zostanie on odczytany i zapisany w naturalny sposób podczas cyklu życia wydarzenia.

Oto kod, który wydaje się robić to, co chcesz, zupełnie naturalnie, bez żadnego triku:

public class AddManyControl : CompositeControl 
{ 
    private void AddControl(int index) 
    { 
     var div = new HtmlGenericControl("div"); 
     var textBox = new TextBox(); 
     textBox.ID = "tb" + index; 
     div.Controls.Add(textBox); 
     Controls.AddAt(index, div); 
    } 

    protected override void CreateChildControls() 
    { 
     for (int i = 0; i < ControlsCount; i++) 
     { 
      AddControl(i); 
     } 

     var btnAdd = new Button(); 
     btnAdd.ID = "Add"; 
     btnAdd.Text = "Add text box"; 
     btnAdd.Click += new EventHandler(btnAdd_Click); 
     Controls.Add(btnAdd); 

     var btnPostBack = new Button(); 
     btnPostBack.ID = "PostBack"; 
     btnPostBack.Text = "Do PostBack"; 
     Controls.Add(btnPostBack); 
    } 

    private int ControlsCount 
    { 
     get 
     { 
      object o = ViewState["ControlCount"]; 
      if (o != null) 
       return (int)o; 

      return 0; 
     } 
     set 
     { 
      ViewState["ControlCount"] = value; 
     } 
    } 

    void btnAdd_Click(object sender, EventArgs e) 
    { 
     int count = ControlsCount; 
     AddControl(count); 
     ControlsCount = count + 1; 
    } 
} 
+0

+1 za rozwiązanie, działa dobrze, byłem ciekaw tego –

+0

, ponieważ wszystkie 'pola tekstowe' dodane ponownie od początku za każdym razem, gdy pojawią się informacje zwrotne, dlaczego przywracają wartości tekstowe? dawka asp.net czy coś? –

+0

@Rami - tak, to magia Viewstate, kiedy działa dobrze :-) –

-2

wierzę trzeba dodać do kontroli stanu widoku.

+0

Nie, to nie działa w ten sposób. To jest coś innego. Niektóre zdarzenia cyklu życia nie są uruchamiane po raz drugi (ponieważ drzewo kontrolne jest odtwarzane). –

Powiązane problemy