ASP.NET: Como acessar repetidor elementos de entrada de formulário gerado?
-
05-07-2019 - |
Pergunta
Estou quer ter um repetidor gerar um monte de caixas de seleção, por exemplo:.
<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>
Pergunta 1:? Como faço individualmente referenciar cada caixa de seleção quando o repetidor está sendo executado para que eu possa definir o valor único
Faça dados-bind i-lo com 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>
Ou eu deveria defini-lo de alguma forma na 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;
}
}
Mas se eu deveria fazer referência a ela no código-behind, como faço para referenciá-lo no código-behind? Eu deveria fazer referência a ela usando o (server-side) propriedade ID de um controle <INPUT>
? i perceber que o ID de um controle no lado do servidor a não é o mesmo que o ID que estará presente no cliente.
ou eu tenho que fazer algo onde eu tenho que encontrar um controle de entrada com um nome de "t" e outra com o nome de "a"? E que tipo de controle é uma caixa de seleção que permite que eu defini-lo do 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;
}
}
Pergunta 2: Quando os cliques posteriores usuário apresentar, como faço para encontrar todos os verificado caixas, ou mais especificamente os seus valores?
Eu tenho que 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);
}
}
}
é o item repetidor dataItem ainda lá em um manipulador de eventos click?
Solução
Use o controle de servidor em vez de fazer um controle de entrada runat = servidor
<asp:CheckBox id="whatever" runat="Server" />
Quando você definir o valor em sua ItemDataBound, você usar FindControl
CheckBox checkBox = (CheckBox)e.Item.FindControl("whatever");
checkBox.Checked = true;
Quando você obter os itens, você também usar FindControl do item em uma construção foreach. Além disso, dependendo de como você ligação de dados que, a DataItem podem não estar mais lá depois de um postback.
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 */ }
}
}
- Muitas pessoas são tentadas a 'cast seguro' usando o operador
as
comFindControl()
. Eu não gosto disso, porque quando você alterar o nome do controle no formulário, você pode silenciosamente ignorar um erro de desenvolvimento e torná-lo mais difícil de rastrear. Eu tento usar apenas o operadoras
se o controle não é garantido para estar lá.
Atualização para:? Qual CheckBox é que no HTML renderizado você vai acabar tendo todos estes nome caixa como
ctl00_cph0_ParentContainer_MyRepeater_ctl01_MyCheckbox
ctl00_cph0_ParentContainer_MyRepeater_ctl02_MyCheckbox
ctl00_cph0_ParentContainer_MyRepeater_ctl03_MyCheckbox
Você não se importa o que os nomes são porque o item.FindControl foreach () recebe-los para você, e você não deve presumir nada sobre eles. No entanto, quando você iterate através foreach, você geralmente precisa de uma forma de referência, que volta a algo. Na maioria das vezes isso é feito por também ter um controle asp: HiddenField ao lado de cada caixa de seleção para manter um identificador para combiná-lo backup para a entidade correta.
Nota de Segurança : há um problema de segurança com o uso de campos ocultos porque um campo oculto pode ser alterada em javascript; sempre estar consciente de que este valor poderia ter sido modificado pelo usuário antes que o formulário foi submetido.
Outras dicas
Você pode achar que é mais fácil de usar um controle CheckBoxList.
No caso simples, você definiria o DataTextVield eo DataValueField ao nome e valor como puxado sua fonte de dados (supondo que você está povoamento a partir de uma fonte de dados) e, em seguida, vinculá-lo a criar os itens.
Provavelmente menos trabalho em sua parte do que criar as caixas de seleção em um repetidor.
Aqui está um código específico para como lidar com o campo oculto:
marcação:
<asp:HiddenField ID="repeaterhidden" Value='<%# DataBinder.Eval(Container.DataItem, "value")%>' runat="server" >
C #:
{
HiddenField hiddenField = (HiddenField)item.FindControl(repeaterStringhidden);
{ /* do something with hiddenField.Value */
}
Eu acredito que esta KB me deu a melhor resposta:
http://msdn.microsoft.com/en-us/library/ 1d04y8ss.aspx
à minha própria falta de sorte, este parece ser disponível apenas para a versão .NET 4.0 (e eu ainda estou preso em 3.5 SP1).
citando (negrito é meu):
Quando um comando está dentro de um controlo de dados-ligado que gera ocorrências repetidas do controlo, o ASP.NET gera fortes <> valores UniqueID e ClientID para cada instância > fortes do controlo. O valor UniqueID é gerado pela combinação de valor do recipiente de nomenclatura UniqueID, valor ID do controlo, e um número sequencial. Este é o caso de controles, como o DataList, Repeater , controles GridView e ListView.
ASP.NET gera valores de ClientID de forma semelhante quando a propriedade ClientIDMode está definido para AutoID. Isso pode tornar difícil para referenciar o controle no script de cliente, porque você normalmente não é possível prever os valores dos números sequenciais que são utilizados. Se você quiser os controles de acesso de dados-ligado a partir de script de cliente, você pode definir a propriedade ClientIDMode a previsível. Isto torna mais fácil de prever o que os valores ClientID será.
Quando você definir o ClientIDMode a previsível, você pode também definir a propriedade ClientIDRowSuffixDataKeys para o nome de um campo de dados que é único , tais como chave primária em uma tabela de banco de dados. Isso faz com que ASP.NET para gerar um ID do cliente que será mais fácil de prever e referência no script de cliente se você pode prever os dados valores-chave.
Assim, na versão 3.5, eu estou fazendo isso 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;
}
}