i'm want to have a repeater generate a bunch of checkboxes, e.g.:
我希望有一个转发器生成一堆复选框,例如:
<tr><td><input type="checkbox" name="t" value="11cbf4deb87" /> <input type="checkbox" name="a" value="33cbf4deb87" />*.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: How do i individually reference each checkbox when the repeater is running so i can set the unique value?
问题1:如何在转发器运行时单独引用每个复选框,以便设置唯一值?
Do i data-bind it with something like:
我用以下内容对数据进行数据绑定:
<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>
Or am i supposed to set it somehow in the OnItemDataBound?
或者我应该在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;
}
}
But if i'm supposed to reference it in the code-behind, how do i reference it in the code-behind? Am i supposed to reference it using the (server-side) id property of an <INPUT>
control? i realize that the ID of a control on the server-side is not the same as the ID that will be present on the client.
但是,如果我应该在代码隐藏中引用它,我如何在代码隐藏中引用它?我应该使用控件的(服务器端)id属性来引用它吗?我意识到服务器端控件的ID与客户端上的ID不同。
Or do i have to do something where i have to find an INPUT control with a name of "t" and another with a name of "a"? And what kind of control is a CheckBox that allows me to set it's input value?
或者我必须做一些事情,我必须找到一个名为“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;
}
}
Question 2: When the user later clicks SUBMIT, how do i find all the checked checkboxes, or more specifically their VALUES?
问题2:当用户稍后单击“提交”时,如何找到所有选中的复选框,或者更具体地说是他们的值?
Do i have to FindControl?
我需要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);
}
}
}
Is the repeater items DataItem still there on a click event handler?
转发器项DataItem是否仍然存在于单击事件处理程序中?
4 个解决方案
#1
13
Use the server control instead of making an input control runat=server
使用服务器控件而不是输入控件runat = server
<asp:CheckBox id="whatever" runat="Server" />
When you set the value in your ItemDataBound, you use FindControl
在ItemDataBound中设置值时,使用FindControl
CheckBox checkBox = (CheckBox)e.Item.FindControl("whatever");
checkBox.Checked = true;
When you get the items, you also use FindControl from the item in a foreach construct. Also, depending on how you databound it, the DataItem may no longer be there after a postback.
获取项目时,还可以使用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 */ }
}
}
- Many people are tempted to 'safe cast' using the
as
operator withFindControl()
. I don't like that because when you change the control name on the form, you can silently ignore a development error and make it harder to track down. I try to only use theas
operator if the control isn't guaranteed to be there. - 很多人都喜欢使用带有FindControl()的as运算符进行'安全强制转换'。我不喜欢这样,因为当您更改表单上的控件名称时,您可以默默地忽略开发错误并使其更难跟踪。如果不能保证控件在那里,我尝试只使用as运算符。
Update for: Which CheckBox is which? In the rendered html you'll end up having all these checkbox name like
更新:哪个CheckBox是哪个?在渲染的html中,你最终会得到所有这些复选框名称
ctl00_cph0_ParentContainer_MyRepeater_ctl01_MyCheckbox
ctl00_cph0_ParentContainer_MyRepeater_ctl02_MyCheckbox
ctl00_cph0_ParentContainer_MyRepeater_ctl03_MyCheckbox
You don't care what the names are because the foreach item.FindControl() gets them for you, and you shouldn't assume anything about them. However, when you iterate via foreach, you usually need a way to reference that back to something. Most of the time this is done by also having an asp:HiddenField control alongside each CheckBox to hold an identifier to match it back up to the correct entity.
你不关心名字是什么,因为foreach item.FindControl()为你获取它们,你不应该假设它们。但是,当您通过foreach进行迭代时,通常需要一种方法来将其引用回某些东西。大多数情况下,这是通过在每个CheckBox旁边都有一个asp:HiddenField控件来保存标识符以使其与正确的实体匹配。
Security note: there is a security issue with using hidden fields because a hidden field can be altered in javascript; always be conscious that this value could have been modified by the user before the form was submitted.
安全说明:使用隐藏字段存在安全问题,因为隐藏字段可以在javascript中更改;始终意识到在提交表单之前用户可能已修改此值。
#2
4
You might find it easier to use a CheckBoxList control.
您可能会发现使用CheckBoxList控件更容易。
In the simple case, you would set the DataTextVield and the DataValueField to the name and value as pulled from your datasource (assuming you're populating from a datasource) and then bind it to create the items.
在简单的情况下,您可以将DataTextVield和DataValueField设置为从数据源中提取的名称和值(假设您从数据源填充),然后绑定它以创建项目。
Probably less work on your part than creating the checkboxes in a repeater.
您可能比在转发器中创建复选框更少的工作。
#3
2
Here is some specific code for how to handle the hidden field:
以下是如何处理隐藏字段的一些特定代码:
MARKUP:
加价:
<asp:HiddenField ID="repeaterhidden" Value='<%# DataBinder.Eval(Container.DataItem, "value")%>' runat="server" >
C#:
C#:
{
{
HiddenField hiddenField = (HiddenField)item.FindControl(repeaterStringhidden);
{ /* do something with hiddenField.Value */
}
}
#4
1
I believe this KB gave me the best answer:
我相信这个KB给了我最好的答案:
http://msdn.microsoft.com/en-us/library/1d04y8ss.aspx
http://msdn.microsoft.com/en-us/library/1d04y8ss.aspx
to my own lack of luck, this seems to be available for the .net 4.0 version only (and I'm still stuck at 3.5 SP1).
对于我自己的运气不足,这似乎仅适用于.net 4.0版本(我仍然坚持在3.5 SP1)。
quoting (bold is mine):
引用(粗体是我的):
When a control is inside a data-bound control that generates repeated instances of the control, ASP.NET generates UniqueID and ClientID values for each instance of the control. The UniqueID value is generated by combining the naming container's UniqueID value, the control's ID value, and a sequential number. This is the case in controls such as the DataList, Repeater, GridView, and ListView controls.
当控件位于生成控件重复实例的数据绑定控件内时,ASP.NET会为控件的每个实例生成UniqueID和ClientID值。通过组合命名容器的UniqueID值,控件的ID值和序号来生成UniqueID值。在诸如DataList,Repeater,GridView和ListView控件之类的控件中就是这种情况。
ASP.NET generates ClientID values in a similar manner when the ClientIDMode property is set to AutoID. This can make it difficult to reference the control in client script, because you typically cannot predict the values of the sequential numbers that are used. If you want to access data-bound controls from client script, you can set the ClientIDMode property to Predictable. This makes it easier to predict what the ClientID values will be.
当ClientIDMode属性设置为AutoID时,ASP.NET以类似的方式生成ClientID值。这可能会使在客户端脚本中引用控件变得困难,因为您通常无法预测所使用的序列号的值。如果要从客户端脚本访问数据绑定控件,可以将ClientIDMode属性设置为Predictable。这样可以更轻松地预测ClientID值。
When you set the ClientIDMode to Predictable, you can also set the ClientIDRowSuffixDataKeys property to the name of a data field that is unique, such as the primary key in a database table. This causes ASP.NET to generate a client ID that will be easier to predict and reference in client script if you can predict data key values.
将ClientIDMode设置为Predictable时,还可以将ClientIDRowSuffixDataKeys属性设置为唯一的数据字段的名称,例如数据库表中的主键。这会导致ASP.NET生成一个客户端ID,如果您可以预测数据键值,则该客户端ID将更容易在客户端脚本中进行预测和引用。
So, in version 3.5, I'm doing it using hidden fields:
所以,在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;
}
}
#1
13
Use the server control instead of making an input control runat=server
使用服务器控件而不是输入控件runat = server
<asp:CheckBox id="whatever" runat="Server" />
When you set the value in your ItemDataBound, you use FindControl
在ItemDataBound中设置值时,使用FindControl
CheckBox checkBox = (CheckBox)e.Item.FindControl("whatever");
checkBox.Checked = true;
When you get the items, you also use FindControl from the item in a foreach construct. Also, depending on how you databound it, the DataItem may no longer be there after a postback.
获取项目时,还可以使用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 */ }
}
}
- Many people are tempted to 'safe cast' using the
as
operator withFindControl()
. I don't like that because when you change the control name on the form, you can silently ignore a development error and make it harder to track down. I try to only use theas
operator if the control isn't guaranteed to be there. - 很多人都喜欢使用带有FindControl()的as运算符进行'安全强制转换'。我不喜欢这样,因为当您更改表单上的控件名称时,您可以默默地忽略开发错误并使其更难跟踪。如果不能保证控件在那里,我尝试只使用as运算符。
Update for: Which CheckBox is which? In the rendered html you'll end up having all these checkbox name like
更新:哪个CheckBox是哪个?在渲染的html中,你最终会得到所有这些复选框名称
ctl00_cph0_ParentContainer_MyRepeater_ctl01_MyCheckbox
ctl00_cph0_ParentContainer_MyRepeater_ctl02_MyCheckbox
ctl00_cph0_ParentContainer_MyRepeater_ctl03_MyCheckbox
You don't care what the names are because the foreach item.FindControl() gets them for you, and you shouldn't assume anything about them. However, when you iterate via foreach, you usually need a way to reference that back to something. Most of the time this is done by also having an asp:HiddenField control alongside each CheckBox to hold an identifier to match it back up to the correct entity.
你不关心名字是什么,因为foreach item.FindControl()为你获取它们,你不应该假设它们。但是,当您通过foreach进行迭代时,通常需要一种方法来将其引用回某些东西。大多数情况下,这是通过在每个CheckBox旁边都有一个asp:HiddenField控件来保存标识符以使其与正确的实体匹配。
Security note: there is a security issue with using hidden fields because a hidden field can be altered in javascript; always be conscious that this value could have been modified by the user before the form was submitted.
安全说明:使用隐藏字段存在安全问题,因为隐藏字段可以在javascript中更改;始终意识到在提交表单之前用户可能已修改此值。
#2
4
You might find it easier to use a CheckBoxList control.
您可能会发现使用CheckBoxList控件更容易。
In the simple case, you would set the DataTextVield and the DataValueField to the name and value as pulled from your datasource (assuming you're populating from a datasource) and then bind it to create the items.
在简单的情况下,您可以将DataTextVield和DataValueField设置为从数据源中提取的名称和值(假设您从数据源填充),然后绑定它以创建项目。
Probably less work on your part than creating the checkboxes in a repeater.
您可能比在转发器中创建复选框更少的工作。
#3
2
Here is some specific code for how to handle the hidden field:
以下是如何处理隐藏字段的一些特定代码:
MARKUP:
加价:
<asp:HiddenField ID="repeaterhidden" Value='<%# DataBinder.Eval(Container.DataItem, "value")%>' runat="server" >
C#:
C#:
{
{
HiddenField hiddenField = (HiddenField)item.FindControl(repeaterStringhidden);
{ /* do something with hiddenField.Value */
}
}
#4
1
I believe this KB gave me the best answer:
我相信这个KB给了我最好的答案:
http://msdn.microsoft.com/en-us/library/1d04y8ss.aspx
http://msdn.microsoft.com/en-us/library/1d04y8ss.aspx
to my own lack of luck, this seems to be available for the .net 4.0 version only (and I'm still stuck at 3.5 SP1).
对于我自己的运气不足,这似乎仅适用于.net 4.0版本(我仍然坚持在3.5 SP1)。
quoting (bold is mine):
引用(粗体是我的):
When a control is inside a data-bound control that generates repeated instances of the control, ASP.NET generates UniqueID and ClientID values for each instance of the control. The UniqueID value is generated by combining the naming container's UniqueID value, the control's ID value, and a sequential number. This is the case in controls such as the DataList, Repeater, GridView, and ListView controls.
当控件位于生成控件重复实例的数据绑定控件内时,ASP.NET会为控件的每个实例生成UniqueID和ClientID值。通过组合命名容器的UniqueID值,控件的ID值和序号来生成UniqueID值。在诸如DataList,Repeater,GridView和ListView控件之类的控件中就是这种情况。
ASP.NET generates ClientID values in a similar manner when the ClientIDMode property is set to AutoID. This can make it difficult to reference the control in client script, because you typically cannot predict the values of the sequential numbers that are used. If you want to access data-bound controls from client script, you can set the ClientIDMode property to Predictable. This makes it easier to predict what the ClientID values will be.
当ClientIDMode属性设置为AutoID时,ASP.NET以类似的方式生成ClientID值。这可能会使在客户端脚本中引用控件变得困难,因为您通常无法预测所使用的序列号的值。如果要从客户端脚本访问数据绑定控件,可以将ClientIDMode属性设置为Predictable。这样可以更轻松地预测ClientID值。
When you set the ClientIDMode to Predictable, you can also set the ClientIDRowSuffixDataKeys property to the name of a data field that is unique, such as the primary key in a database table. This causes ASP.NET to generate a client ID that will be easier to predict and reference in client script if you can predict data key values.
将ClientIDMode设置为Predictable时,还可以将ClientIDRowSuffixDataKeys属性设置为唯一的数据字段的名称,例如数据库表中的主键。这会导致ASP.NET生成一个客户端ID,如果您可以预测数据键值,则该客户端ID将更容易在客户端脚本中进行预测和引用。
So, in version 3.5, I'm doing it using hidden fields:
所以,在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;
}
}