2008-10-07 23 views
10

he perdido desea tener un repetidor de generar un montón de casillas de verificación, por ejemplo .:ASP.NET: ¿Cómo acceder a los elementos de entrada de formulario generados por repetidor?

<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> 

Pregunta 1: ¿Cómo me refiero individualmente cada casilla cuando el repetidor está en funcionamiento para que pueda establecer el valor único?

hacer yo datos se unen con algo como:

<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> 

O se supone que debo configurar de alguna manera en el 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; 
    } 
} 

Pero si se supone que debo hacer referencia a ella en el código subyacente, ¿cómo hacer referencia a ella en el código subyacente? ¿Se supone que debo referenciarlo usando la propiedad de identificación (del lado del servidor) de un control <INPUT>? me doy cuenta de que la ID de un control en el lado del servidor no es lo mismo que la ID que estará presente en el cliente.

¿O tengo que hacer algo donde tengo que encontrar un control INPUT con un nombre de "t" y otro con un nombre de "a"? ¿Y qué tipo de control es un CheckBox que me permite establecer su valor de entrada?

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; 
    } 
} 

Pregunta 2: Cuando el usuario hace clic en Enviar posteriores, ¿cómo puedo encontrar todas las casillas revisadas, o más específicamente sus valores?

¿Debo 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); 
     } 
    } 
} 

¿Los elementos del repetidor DataItem siguen ahí en un controlador de eventos de clic?

Respuesta

13

Utilice el control de servidor en lugar de hacer una runat control de entrada = servidor

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

Cuando se establece el valor en su ItemDataBound, utiliza FindControl

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

Al llegar los elementos, también use FindControl del elemento en una construcción foreach. Además, dependiendo de cómo lo haya conectado a datos, es posible que DataItem ya no esté allí después de una devolución de datos.

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 */ } 
    } 
} 
  • Muchas personas se ven tentados a 'fundido seguro' mediante el operador as con FindControl(). No me gusta porque cuando cambias el nombre del control en el formulario, puedes ignorar silenciosamente un error de desarrollo y dificultar el rastreo. Intento utilizar solo el operador as si no se garantiza que el control esté allí.

Actualización para: ¿Qué CheckBox es cuál? En el HTML representado que va a terminar con todos estos nombre casilla como

ctl00_cph0_ParentContainer_MyRepeater_ctl01_MyCheckbox 
ctl00_cph0_ParentContainer_MyRepeater_ctl02_MyCheckbox 
ctl00_cph0_ParentContainer_MyRepeater_ctl03_MyCheckbox 

No te importa lo que los nombres se deben a que el foreach item.FindControl() los sufran por ti, y que no debería asumir algo sobre ellos. Sin embargo, cuando itera a través de foreach, generalmente necesita una forma de hacer referencia a eso de nuevo. La mayoría de las veces esto se hace teniendo también un control asp: HiddenField junto a cada CheckBox para mantener un identificador que lo haga coincidir con la entidad correcta.

Nota de seguridad: existe un problema de seguridad con el uso de campos ocultos porque un campo oculto puede ser alterado en javascript; Siempre tenga en cuenta que este valor podría haber sido modificado por el usuario antes de enviar el formulario.

+0

¿Cuál es la forma preferida de saber qué casilla de verificación es esta? Habrá docenas de casillas de verificación "lo que sea". Es apropiado usar checkbox.Attributes ["value"]? –

+0

He actualizado la respuesta con una forma de emparejar la casilla de verificación (o cualquier control) en un repetidor usando un campo oculto. –

+0

No se olvide: if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem) {... –

4

Puede que le resulte más fácil usar un control CheckBoxList.

En el caso simple, establecería DataTextVield y DataValueField en el nombre y valor extraídos de su fuente de datos (suponiendo que está rellenando desde un origen de datos) y luego lo vinculará para crear los elementos.

Probablemente menos trabajo de su parte que crear las casillas de verificación en un repetidor.

+1

específicamente agregué dos casillas de verificación para forzar una respuesta a esta pregunta conceptual; de lo contrario, las personas intentan encontrar atajos. –

+0

Actualmente tengo la necesidad de agregar algunos detalles adicionales a mi lista de casillas de verificación, un tercer elemento de datos, y por lo tanto no puedo usar un control CheckBoxList, sino un Repeater. –

2

Aquí hay un código específico para cómo manejar el campo oculto:

MARCADO:

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

C#:

{

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

{ /* do something with hiddenField.Value */ 

}

1

I Cree esto KB me dio la mejor respuesta:

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

a mi propia falta de suerte, esto parece estar disponible para la versión .NET 4.0 sólo (y todavía estoy atascado en 3.5 SP1).

citando (negrita es mía):

Cuando un control está dentro de un control enlazado a datos que genera repetidas instancias del control, ASP.NET genera valores UniqueID y ClientID para cada instancia de la controlar. El valor UniqueID se genera combinando el valor UniqueID del contenedor de nombres, el valor de ID del control y un número secuencial. Este es el caso de controles como DataList, Repeater, GridView y ListView.

ASP.NET genera valores ClientID de manera similar cuando la propiedad ClientIDMode está configurada en AutoID. Esto puede hacer que sea difícil hacer referencia al control en el script del cliente, ya que normalmente no puede predecir los valores de los números secuenciales que se utilizan. Si desea acceder a los controles enlazados a datos desde el script del cliente, puede establecer la propiedad ClientIDMode en Predecible. Esto hace que sea más fácil predecir cuáles serán los valores de ClientID.

Cuando se establece el ClientIDMode a predecible, puede también establecer la propiedad ClientIDRowSuffixDataKeys al nombre de un campo de datos que es único, tales como la clave principal en una tabla de base de datos. Esto hace que ASP.NET genere una ID de cliente que será más fácil de predecir y hacer referencia en la secuencia de comandos del cliente si puede predecir valores de clave de datos.

Así, en la versión 3.5, lo hago usando campos ocultos:

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; 
     } 
    } 
Cuestiones relacionadas