ASP.NET: Comment accéder aux éléments d’entrée de formulaire générés par le répéteur?

StackOverflow https://stackoverflow.com/questions/179938

  •  05-07-2019
  •  | 
  •  

Question

Je souhaite qu'un répéteur génère un ensemble de cases à cocher, par exemple:

<tr><td><input type="checkbox" name="t" value="11cbf4deb87" /> <input type="checkbox" name="a" value="33cbf4deb87" />stackoverflow.com</td></tr>
<tr><td><input type="checkbox" name="t" value="11cbf4deb88" /> <input type="checkbox" name="a" value="33cbf4deb87" />microsoft.com</td></tr>
<tr><td><input type="checkbox" name="t" value="11cd3f33a89" /> <input type="checkbox" name="a" value="33cbf4deb87" />gmail.com</td></tr>
<tr><td><input type="checkbox" name="t" value="1138fecd337" /> <input type="checkbox" name="a" value="33cbf4deb87" />youporn.com</td></tr>
<tr><td><input type="checkbox" name="t" value="11009efdacc" /> <input type="checkbox" name="a" value="33bf4deb87" />fantasti.cc</td></tr>

Question 1: Comment référencer individuellement chaque case à cocher lorsque le répéteur est en cours d'exécution afin de pouvoir définir la valeur unique?

Dois-je le lier avec quelque chose comme:

<itemtemplate>
   <tr>
      <td>
         <input type="checkbox" name="t" 
            value="<%# ((Item)Container.DataItem).TangoUniquifier %>" />
         <input type="checkbox" name="a" 
            value="<%# ((Item)Container.DataItem).AlphaUniquifier %>" />
         <%# ((Item)Container.DataItem).SiteName %>
      </td>
   </tr>
</itemtemplate>

Ou suis-je censé le définir d'une manière ou d'une autre dans OnItemDataBound?

<asp:repeater id="ItemsRepeater" 
      OnItemDataBound="ItemsRepeater_OnItemDataBound" runat="server">
   ...
   <itemtemplate>
      <tr>
         <td>
            <input id="chkTango" type="checkbox" name="t" runat="server" />
            <input id="chkAlpha" type="checkbox" name="a" runat="server" />
            <%# ((Item)Container.DataItem).SiteName %>
         </td>
      </tr>
   </itemtemplate>
   ...
</asp:repeater>


protected void ItemsRepeater_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
   // if the data bound item is an item or alternating item (not the header etc)
   if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
   {
      // get the associated item
      Item item = (Item)e.Item.DataItem;

      //???
      this.chkTango.Value = item.TangoUniquifier;
      this.chkAlpha.Value = item.AlphaUniquifier;
   }
}

Mais si je suis censé le référencer dans le code-behind, comment puis-je le référencer dans le code-behind? Suis-je censé le référencer à l'aide de la propriété id (côté serveur) d'un contrôle <INPUT>? Je me rends compte que l’ID d’un contrôle côté serveur n’est pas le même que celui qui sera présent sur le client.

Ou dois-je faire quelque chose pour lequel je dois trouver un contrôle INPUT portant le nom & "; t &"; et un autre avec le nom & "; un &"; Et quel type de contrôle est un CheckBox qui me permet de définir sa valeur d'entrée?

protected void ItemsRepeater_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
   // if the data bound item is an item or alternating item (not the header etc)
   if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
   {
      // get the associated item
      Item item = (Item)e.Item.DataItem;

      CheckBox chkTango = (CheckBox)e.Item.FindControl("chkTango");
      chkTango.Value = item.TangoUniquifier;

      CheckBox chkAlpha = (CheckBox)e.Item.FindControl("chkAlpha");
      chkAlpha.Value = item.AlphaUniquifier;
   }
}

Question 2: Lorsque l’utilisateur clique ensuite sur ENVOYER, comment trouver toutes les cases à cocher cochées ou plus précisément leurs VALEURS?

Dois-je trouver FindControl?

protected void DoStuffWithLinks_Click(object sender, EventArgs e)
{
   // loop through the repeater items
   foreach (RepeaterItem repeaterItem in actionItemRepeater.Items)
   {
      Item item = repeaterItem.DataItem as Item;

      // grab the checkboxes
      CheckBox chkAlpha = (CheckBox)repeaterItem.FindControl("chkAlpha");
      CheckBox chkTango = (CheckBox)repeaterItem.FindControl("chkTango");

      if (chkAlpha.Checked)
      {          
         item.DoAlphaStuff(chkAlpha.Name);
      }

      if (chkTango.Checked)
      {
         item.DoTangoStuff(chkTango.Name);
      }
   }
}

Les éléments de répéteur DataItem sont-ils toujours présents sur un gestionnaire d'événements de clic?

Était-ce utile?

La solution

Utilisez le contrôle serveur au lieu de créer un contrôle d'entrée runat = server

 <asp:CheckBox id="whatever" runat="Server" />

Lorsque vous définissez la valeur dans votre ItemDataBound, vous utilisez FindControl

CheckBox checkBox = (CheckBox)e.Item.FindControl("whatever");
checkBox.Checked = true;

Lorsque vous récupérez les éléments, vous utilisez également FindControl à partir de l’élément d’une construction foreach. De plus, en fonction de la façon dont vous utilisez la date, le DataItem peut ne plus être là après une publication.

foreach (RepeaterItem item in myRepeater.Items)
{
    if (item.ItemType == ListItemType.Item 
        || item.ItemType == ListItemType.AlternatingItem) 
    { 
        CheckBox checkBox = (CheckBox)item.FindControl("whatever");
        if (checkBox.Checked)
        { /* do something */ }
    }
}
  • De nombreuses personnes sont tentées de "diffuser en toute sécurité" à l'aide de l'opérateur as avec FindControl(). Je n'aime pas cela car, lorsque vous modifiez le nom du contrôle sur le formulaire, vous pouvez ignorer en silence une erreur de développement et rendre la recherche plus difficile. J'essaie d'utiliser l'opérateur <=> uniquement si le contrôle n'est pas garanti.

Mise à jour pour: Quel CheckBox est lequel? Dans le code HTML rendu, vous aurez tous ces noms de cases à cocher comme

ctl00_cph0_ParentContainer_MyRepeater_ctl01_MyCheckbox
ctl00_cph0_ParentContainer_MyRepeater_ctl02_MyCheckbox
ctl00_cph0_ParentContainer_MyRepeater_ctl03_MyCheckbox

Vous ne vous souciez pas des noms parce que l'élément foreach.FindControl () les obtient pour vous et vous ne devez rien en déduire. Cependant, lorsque vous effectuez une itération sur foreach, vous avez généralement besoin d'un moyen de faire référence à cela. La plupart du temps, cela se fait en ayant également un contrôle asp: HiddenField à côté de chaque case à cocher pour contenir un identifiant pour le faire correspondre à l'entité correcte.

Note de sécurité : l'utilisation de champs cachés pose un problème de sécurité, car un champ caché peut être modifié en javascript; sachez toujours que cette valeur aurait pu être modifiée par l'utilisateur avant l'envoi du formulaire.

Autres conseils

Vous trouverez peut-être plus facile d'utiliser un contrôle CheckBoxList.

Dans le cas simple, définissez DataTextVield et DataValueField sur le nom et la valeur extraits de votre source de données (en supposant que vous les remplissiez à partir d'une source de données), puis reliez-le pour créer les éléments.

Probablement moins de travail de votre part que la création des cases à cocher dans un répéteur.

Voici un code spécifique expliquant comment gérer le champ caché:

MARKUP:

<asp:HiddenField ID="repeaterhidden" Value='<%# DataBinder.Eval(Container.DataItem, "value")%>' runat="server" >

C #:

{

HiddenField hiddenField = (HiddenField)item.FindControl(repeaterStringhidden);

{ /* do something with hiddenField.Value */

}

Je pense que cette base de connaissances m'a apporté la meilleure réponse:

http://msdn.microsoft.com/en-us/library/ 1d04y8ss.aspx

à mon propre manque de chance, cela semble être disponible pour la version .net 4.0 uniquement (et je suis toujours bloqué à 3.5 SP1).

citant (gras est le mien):

  

Lorsqu'un contrôle est à l'intérieur d'un contrôle lié aux données qui génère des instances répétées du contrôle, ASP.NET génère des valeurs UniqueID et ClientID pour chaque instance du contrôle. La valeur UniqueID est générée en combinant la valeur UniqueID du conteneur de nommage, la valeur ID du contrôle et un numéro séquentiel. C'est le cas dans les contrôles tels que les contrôles DataList, Repeater , GridView et ListView.

     

ASP.NET génère les valeurs ClientID de la même manière lorsque la propriété ClientIDMode est définie sur AutoID. Cela peut rendre difficile la référence au contrôle dans le script client, car vous ne pouvez généralement pas prédire les valeurs des nombres séquentiels utilisés. Si vous souhaitez accéder aux contrôles liés aux données à partir du script client, vous pouvez définir la propriété ClientIDMode sur Prédictible. Il est ainsi plus facile de prévoir les valeurs de ClientID.

     

Lorsque vous définissez ClientIDMode sur Predictable, vous pouvez également définir la propriété ClientIDRowSuffixDataKeys sur le nom d'un champ de données unique , tel que la clé primaire dans une table de base de données. Ainsi, ASP.NET génère un ID client qui sera plus facile à prévoir et à référencer dans un script client si vous pouvez prédire les valeurs de clé de données.

Donc, dans la version 3.5, je le fais en utilisant des champs cachés:

    foreach (RepeaterItem item in rptClientes.Items)
    {
        Panel pnl = (Panel)item.FindControl("divCliente");
        Control c = pnl.FindControl("hdnID");
        if (c is HiddenField)
        {
            if (((HiddenField)c).Value == hdnClienteNome.Value)
                pnl.BackColor = System.Drawing.Color.Beige;
        }
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top