2010-05-24 3 views
0

Je remplis le formulaire Web avec la liste dynamique des examens de la base de données. Je souhaite que l'utilisateur entre les notes d'examen pour chaque examen. Il y a une liste de titres d'examen et de zone de texte près de chaque titre.asp.net web forms meilleure pratique pour récupérer les valeurs de contrôle du serveur dynamique

je créer une liste avec un contrôle répéteur (ViewState est désactivé):

<asp:Repeater ID="rptExams" runat="server" onitemdatabound="rptExams_ItemDataBound" >  
     <ItemTemplate>   
       <tr> 
        <td>       
         <asp:Literal runat="server" ID="ltTitle"/> 
        </td> 
        <td> 
         <asp:HiddenField runat="server" ID="hfId"/> 
         <asp:Textbox runat="server" ID="tbMark"/> 
        </td> 
       </tr> 
     </ItemTemplate>  
    </asp:Repeater> 

Et lier des données à répéteur sur Page_Init:

class Exam 
{ 
    public int Id { get; set;} 
    public string Title { get; set;} 
} 
... 
// this list is retrieved from database actually 
Exam[] Exams = new Exam[] 
{ 
    new Exam { Id = 1, Title = "Math"}, 
    new Exam { Id = 2, Title = "History"}           
}; 
... 
protected void Page_Init(object sender, EventArgs e) 
{ 
    rptExams.DataSource = Exams; 
    rptExams.DataBind(); 
} 

Jusqu'à présent, si bon. Ensuite, je dois récupérer des données sur la publication. J'ai deux façons, mais les deux ont l'air moche. L'idée consiste à stocker des contrôles de données créés dynamiquement sur ItemDataBoundEvent dans l'étape Page_Init et à traiter leurs valeurs dans l'étape Page_Load. Il ressemble à ceci:

private Dictionary<HiddenField, TextBox> Id2Mark = new Dictionary<HiddenField, TextBox>(); 

protected void rptExams_ItemDataBound(object sender, RepeaterItemEventArgs e) 
{ 
    ... 
    if (IsPostBack) 
    { 
     var tbMark = (TextBox)e.Item.FindControl("tbMark"); 
     var hfId = (HiddenField)e.Item.FindControl("hfId"); 

     // store dynamically created controls 
     Id2Mark.Add(hfId, tbMark); 
    } 
    ...  
} 

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (IsPostBack) 
    { 
     foreach (var pair in Id2Mark) 
     { 
      int examId = Int32.Parse(pair.Key.Value); 
      string mark = pair.Value.Text; 
      // PROCESS 
     } 
... 

Je suis complètement sûr qu'il existe un meilleur moyen de récupérer des données de contrôles créés dynamiquement. Merci d'avance!

Répondre

1

Voilà comment vous pouvez le faire:

Tout d'abord, ne redéfinissez pas les données lors de la publication - ce n'est pas nécessaire. Ne liez que le premier appel de la page.

protected void Page_Init(object sender, EventArgs e) 
{ 
    if (!IsPostBack){ 
     rptExams.DataSource = Exams; 
     rptExams.DataBind(); 
    } 
} 

Vous n'aurez pas non plus besoin du dictionnaire.

Puis, sur un postback, vous pouvez accéder aux données liées comme suit:

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (IsPostBack) 
    { 
     foreach (RepeaterItem item in rptExams.Items) 
     { 
      HiddenField hfId = item.FindControl("hfId") as HiddenField; 
      TextBox tbMark = item.FindControl("tbMark") as TextBox; 

      int examId = Int32.Parse(hfId); 
      string mark = tbMark.Text; 
      // PROCESS 
     } 
    } 
} 
+0

Ok, merci! Cette approche devrait fonctionner même si ViewState est désactivé. Je peux toujours remplir ma liste sur le serveur, puis répéter les éléments Repeater.Items quand c'est nécessaire! :) –

+0

De rien! Et oui si vous relancez sur chaque publication cela fonctionne aussi avec viewstate désactivé. – marapet

Questions connexes