10

我想让中继器生成一堆复选框,例如:

<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”的输入控件和另一个名称为“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 是否仍然存在于单击事件处理程序上?

4

4 回答 4

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 中更改;请始终注意,在提交表单之前,用户可能已经修改了此值。

于 2008-10-07T20:40:46.120 回答
4

您可能会发现使用 CheckBoxList 控件更容易。

在简单的情况下,您可以将 DataTextVield 和 DataValueField 设置为从数据源中提取的名称和值(假设您从数据源中填充),然后将其绑定以创建项目。

与在中继器中创建复选框相比,您的工作可能更少。

于 2008-10-07T19:31:25.810 回答
2

以下是一些关于如何处理隐藏字段的特定代码:

标记:

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

C#:

{

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

{ /* do something with hiddenField.Value */

}

于 2009-09-01T22:06:19.053 回答
1

我相信这个知识库给了我最好的答案:

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

由于我自己运气不好,这似乎仅适用于 .net 4.0 版本(我仍然停留在 3.5 SP1)。

引用(粗体是我的):

当控件位于生成控件重复实例的数据绑定控件内时,ASP.NET 会为控件的每个实例生成 UniqueID 和 ClientID 值。UniqueID 值是通过组合命名容器的 UniqueID 值、控件的 ID 值和序号生成的。在 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;
        }
    }
于 2012-03-16T12:19:48.257 回答