从后面代码中的click事件中我获得了ItemTemplate中控件的客户端ID(自然地说,为listview中的每个记录创建了控件):
var lastControlWithFocusClientId = "cphContainer_ucTakeTest_lvData_txtAnswer_0";
我需要找到那个控件,所以我试过了:
lvData.FindControl(lastControlWithFocusClientId)
和
Page.FindControl(lastControlWithFocusClientId)
然而两者都返回null(即没有找到控件。)那么我在这里缺少什么?
编辑添加了ListView标记:
<asp:ListView runat="server"
ID="lvData"
ItemType="MyItemType"
SelectMethod="GetQuestions"
OnItemDataBound="lvData_OnItemDataBound" OnItemCreated="lvData_ItemCreated">
<ItemTemplate>
<tr>
<td><span class="label label-info"><%#: Item.QuestionNumber %></span></td>
<td>
<asp:Label ID="lblQuestionText" runat="server" Text='<%# Eval("QuestionText") %>' />
</td>
<td>
<img src='/ImageHandler.ashx?questionNo=<%#: Item.QuestionNumber %>'>
</td>
<td>
<div class="input-group">
<asp:TextBox data-sessionid='<%# SessionsId %>' data-question-no='<%#: Item.QuestionNumber %>' Enabled='<%# !ShowStudentResults %>' CssClass="form-control FlyoutCandidate" ID="txtAnswer" runat="server"></asp:TextBox>
<span data-content='<%#: GetAnswerInstructions(Item.SolutionType) %>' class="input-group-addon flyout-candidate-hint"><span class="glyphicon glyphicon-comment"></span></span>
<span class="input-group-addon special-character-toggle"><span class="glyphicon glyphicon-credit-card"></span></span>
</div>
</td>
<td>
<img runat="server" data-sessionid='<%# SessionsId %>' data-qno='<%# Item.QuestionId %>' data-id='<%# Item.QuestionNumber %>' onclick="javascript: TakeTestJs.DisplayQuestionHelp(this); return false;" src="/Images/help-icon.png" width="32" height="32" alt="" />
</td>
<td>
<asp:Panel runat="server" ID="imgHint"></asp:Panel>
</td>
<td>
<asp:Label CssClass="label label-info" ID="lblStudentMark" runat="server" Text='<%# Item.StudentMark %>' />
</td>
<td>
<asp:Label CssClass="label label-primary" ID="lblOutOf" runat="server" Text='<%# Item.QuestionOutOf %>' />
</td>
<td>
<asp:Label ID="lblSolutionText" runat="server" Text='<%# Item.SolutionText %>' />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
答案 0 :(得分:0)
findcontrol不是递归的,所以你必须做一些解决方法。这是我的代码,我从这里得到的修改版本:
private Control RecursiveFindControl(Control targetControl, string findControlId) {
if (targetControl.HasControls()) {
foreach (Control childControl in targetControl.Controls) {
if (childControl.ID == findControlId) {
return childControl;
}
RecursiveFindControl(childControl, findControlId);
}
}
return null;}
只需使用:
RecursiveFindControl(this, ControlName)
答案 1 :(得分:0)
由于您使用的是.NET4及更高版本,因此您实际上可以设置ClientMode属性并自行设置,这样您甚至不必使用由ASP.NET和嵌套服务器控件生成的令人困惑的ClientID。
查看此MSDN文章了解ClientIDMode
属性
http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientidmode%28v=vs.110%29.aspx
否则,为了更准确地回答你的问题,你不能对控件集合本身进行FindControl,因为它会失败。
通常当我使用ListView时,我最终会获取触发该行事件的控件。
因此,如果我在行中有一个LinkButton,并且我有一个点击事件,我将执行以下操作
protected void btnConfirm_Click(object sender, EventArgs e)
{
LinkButton btn = (LinkButton)sender;
ListViewDataItem row = btn.NamingContainer as ListViewDataItem;
if (row != null)
{
HiddenField hiddenFieldWithSomething = row.FindControl("hiddenControl") as HiddenField;
//var lastControlWithFocusClientId = cphContainer_ucTakeTest_lvData_txtAnswer_0";
if (hiddenFieldWithSomething.ClientID == lastControlWithFocusClientId)
{
//Do something here
}
}
}
当这样做的时候,它会更精细一点,你仍然可以通过典型的事件处理程序。
此问题中发布的RecursiveFindControl帮助程序将为您提供更强大且可重用的解决方案。
答案 2 :(得分:0)
我最终实现了以下递归搜索,因为@ user2930100对我不起作用:
private Control RecursiveFindControl(Control aRootControl, string aFindControlClientId)
{
if (aRootControl.ClientID == aFindControlClientId)
return aRootControl;
foreach (Control ctl in aRootControl.Controls)
{
Control foundControl = RecursiveFindControl(ctl, aFindControlClientId);
if (foundControl != null)
return foundControl;
}
return null;
}