这让我很难过。我试图在动态加载的asp.net Repeater模板中找到一个复选框。模板工作正常,数据绑定很好,一切都很好,但我找不到控件!有什么想法吗?
这是转发器代码(我对具有不同风格的备用模板有类似的代码):
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="template-tasks-
incomplete.ascx.cs" Inherits="controls_template_tasks_incomplete" %>
<ItemTemplate>
<div class="task">
<div class="date"><asp:CheckBox ID="chkIsComplete" runat="server"
AutoPostBack="True" /><%# DataBinder.Eval(((RepeaterItem)Container).DataItem, "DateCreated")%></div>
<div class="description"><%# DataBinder.Eval(((RepeaterItem)Container).DataItem, "TaskDescription")%></div>
</div>
</ItemTemplate>
这是我加载模板的方法(工作正常)
rptTasks.ItemTemplate = LoadTemplate("~/controls/template-tasks-incomplete.ascx");
rptTasks.AlternatingItemTemplate = LoadTemplate("~/controls/template-tasks-incomplete-alt.ascx");
...最后这就是我试图找到复选框的方式(但一直是空的)
protected void rptTasks_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
CheckBox chkBoxIsComplete = (CheckBox)e.Item.FindControl("chkIsComplete");
if (chkBoxIsComplete != null)
{
int taskID = (int)DataBinder.Eval(e.Item.DataItem, "TaskID");
}
}
}
我只能认为复选框埋藏在某个层次结构的更深处,但我不知道如何访问它,因为我认为FindControl会这样做。
这是生成的HTML:
<ItemTemplate>
<div class="task">
<div class="date"><input id="ctl00_ContentPlaceHolder1_rptTasks_ctl00_ctl00_chkIsComplete" type="checkbox" name="ctl00$ContentPlaceHolder1$rptTasks$ctl00$ctl00$chkIsComplete" onclick="javascript:setTimeout('__doPostBack(\'ctl00$ContentPlaceHolder1$rptTasks$ctl00$ctl00$chkIsComplete\',\'\')', 0)" />23/08/2010 11:53:00 PM</div>
<div class="description">test task</div>
</div>
答案 0 :(得分:2)
我将此扩展方法作为我的工具包的一部分:
/// <summary>
/// find the control with the given ID, recursively below the root
/// </summary>
public static Control FindControlRecursive( this ControlCollection root, string id )
{
foreach ( Control control in root )
{
if ( control != null && id.Equals( control.ID, StringComparison.InvariantCultureIgnoreCase ) )
{
return control;
}
else
{
Control result = FindControlRecursive( control.Controls, id );
if ( result != null )
{
return result;
}
}
}
return null;
}
用法:
CheckBox chkBoxIsComplete = (CheckBox)e.Item.Controls.FindControlRecursive("chkIsComplete");
答案 1 :(得分:1)
您未实施OnDataBinding
的{{1}}方法的原因?
示例:
CheckBox
然后在您的代码隐藏中访问它:
<asp:CheckBox ID="chkIsComplete" runat="server"
AutoPostBack="True" OnDataBinding="chkIsComplete_DataBinding" />
此代码将针对EACH数据绑定复选框运行,因此您可以执行任何您需要执行的操作,而无需关心查找控件。通常,这是进行数据绑定的最佳方式,因为它将您的代码范围限制在控件级别,因此您无需在记录级别不断搜索所有内容和硬编码搜索名称。
答案 2 :(得分:0)
您应该查看生成的html以确切了解控件的位置。除非您遍历所有控件及其子控件,否则最终会找到它。
答案 3 :(得分:0)
我之前从未在代码隐藏中使用过设置模板,但似乎如果您生成的HTML包含您所指示的行<ItemTemplate>
,那么某些内容无法正常工作。
答案 4 :(得分:0)
您是否正在使用页眉/页脚模板?如果是,则需要检查调用ItemDataBound()的模板类型。将在每个模板上调用ItemDataBound(),包括页眉和页脚。 HeaderTemplate的存在将在后续ItemTemplates上调用之前触发ItemDataBound(),并且由于感兴趣的控件未包含在头文件中,因此FindControl()无法获得任何内容。通过仅调用FindControl(),其中调用ItemDataBound()的项类型是Item / AlternatingItem,可以防止返回null / Nothing,徒劳无法搜索控件。
<asp:Repeater ID="rpt" runat="server" OnItemDataBound="rpt_ItemDataBound">
<HeaderTemplate><table><tr><td>Header</td></tr></HeaderTemplate>
<ItemTemplate><tr><td><asp:button id="Button" runat="server"/></td></tr></ItemTemplate>
<FooterTemplate><tr><td>Footer</td></tr></table></FooterTemplate>
</asp:Repeater>
Protected Sub rpt_ItemDataBound(sender As Object, e As System.Web.UI.WebControls.RepeaterItemEventArgs)
If (e.Item.ItemType = ListItemType.Item) Or (e.Item.ItemType = ListItemType.AlternatingItem) Then
Dim Button As Button = CType(e.Item.FindControl("Button"), Button)
End If
End Sub