我想让转发器生成一堆复选框,例如:
<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>
问题1:如何在转发器运行时单独引用每个复选框,以便设置唯一值?
我是否使用以下内容进行数据绑定:
<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>
或者我应该在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;
}
}
但是如果我应该在代码隐藏中引用它,我如何在代码隐藏中引用它?我应该使用<INPUT>
控件的(服务器端)id属性来引用它吗?我意识到服务器端控件的ID与客户端上的ID不同。
或者我必须做一些事情,我必须找到一个名为“t”的INPUT控件和另一个名为“a”的控件?什么样的控件是CheckBox,它允许我设置它的输入值?
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;
}
}
问题2: 当用户稍后点击“提交”时,我如何找到所有选中的复选框,或者更具体地说是他们的值?
我必须使用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);
}
}
}
转发器项DataItem是否仍然存在于单击事件处理程序中?
答案 0 :(得分:13)
使用服务器控件而不是输入控件runat = server
<asp:CheckBox id="whatever" runat="Server" />
在ItemDataBound中设置值时,使用FindControl
CheckBox checkBox = (CheckBox)e.Item.FindControl("whatever");
checkBox.Checked = true;
获取项目时,还可以使用foreach构造中项目的FindControl。此外,根据您对数据库进行数据处理的方式,在回发后,DataItem可能不再存在。
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 */ }
}
}
as
运算符FindControl()
进行“安全投射”。我不喜欢这样,因为当您更改表单上的控件名称时,您可以默默地忽略开发错误并使其更难跟踪。如果不能保证控件在那里,我会尝试仅使用as
运算符。更新:哪个CheckBox是哪个?在渲染的html中,你最终会得到所有这些复选框名称,如
ctl00_cph0_ParentContainer_MyRepeater_ctl01_MyCheckbox
ctl00_cph0_ParentContainer_MyRepeater_ctl02_MyCheckbox
ctl00_cph0_ParentContainer_MyRepeater_ctl03_MyCheckbox
你不关心名字是什么,因为foreach item.FindControl()为你获取它们,你不应该假设它们。但是,当您通过foreach进行迭代时,通常需要一种方法来将其引用回某些东西。大多数情况下,这是通过在每个CheckBox旁边使用asp:HiddenField控件来保存标识符以将其匹配回正确的实体来完成的。
安全提示:使用隐藏字段存在安全问题,因为隐藏字段可以在javascript中更改;始终意识到在提交表单之前用户可能已修改此值。
答案 1 :(得分:4)
您可能会发现使用CheckBoxList控件更容易。
在简单的情况下,您可以将DataTextVield和DataValueField设置为从数据源中提取的名称和值(假设您从数据源填充),然后绑定它以创建项目。
与在转发器中创建复选框相比,您的工作量可能更少。
答案 2 :(得分:2)
以下是如何处理隐藏字段的一些具体代码:
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 */
}
答案 3 :(得分:1)
我相信这个KB给了我最好的答案:
http://msdn.microsoft.com/en-us/library/1d04y8ss.aspx
我自己运气不好,这似乎仅适用于.net 4.0版本(我仍然坚持使用3.5 SP1)。
引用(粗体是我的):
当控件位于生成控件重复实例的数据绑定控件内时,ASP.NET会为控件的每个实例生成 UniqueID和ClientID值。通过组合命名容器的UniqueID值,控件的ID值和序列号生成UniqueID值。在控件中就是这种情况,例如DataList, Repeater ,GridView和ListView控件。
当ClientIDMode属性设置为AutoID时,ASP.NET以类似的方式生成ClientID值。这可能使在客户端脚本中引用控件变得困难,因为您通常无法预测所使用的序列号的值。如果要从客户端脚本访问数据绑定控件,可以将ClientIDMode属性设置为Predictable。这样可以更容易地预测ClientID值的内容。
当您将ClientIDMode设置为Predictable时,您也可以将ClientIDRowSuffixDataKeys属性设置为唯一的数据字段名称,例如数据库表中的主键。这会导致ASP.NET生成一个客户端ID,如果您可以预测数据键值,则可以更容易地在客户端脚本中进行预测和引用。
因此,在3.5版本中,我使用隐藏字段进行操作:
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;
}
}