C# 当我有控件的clientid时,是否在asp:listview中找到该控件? VS2012、.NET 4.51、WebForms

C# 当我有控件的clientid时,是否在asp:listview中找到该控件? VS2012、.NET 4.51、WebForms,c#,listview,webforms,C#,Listview,Webforms,通过代码隐藏中的单击事件,我获得了ItemTemplate中控件的客户端ID(当然,所述控件是为listview中的每个记录创建的): 我需要找到那个控件,所以我尝试: lvData.FindControl(lastControlWithFocusClientId) 及 然而,两者都返回null(即未找到控件)。那么我在这里缺少什么呢 编辑添加了ListView标记: <asp:ListView runat="server" ID=

通过代码隐藏中的单击事件,我获得了ItemTemplate中控件的客户端ID(当然,所述控件是为listview中的每个记录创建的):

我需要找到那个控件,所以我尝试:

lvData.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>

'>

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)

由于您使用的是.NET4及更高版本,因此实际上可以设置ClientMode属性并自行设置,这样您甚至不必使用ASP.NET和嵌套服务器控件生成的令人困惑的ClientID

查看这篇MSDN文章,了解
ClientIDMode
属性

否则,为了更准确地回答您的问题,您不能对控件集合本身执行FindControl,因为它将失败

通常,当我使用ListView时,我最终会使用触发该行事件的控件

因此,如果行中有一个LinkButton,并且有一个click事件,我将执行以下操作

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帮助程序将为您提供一个更加健壮和可重用的解决方案。

我最终实现了以下递归搜索,因为@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;
    }

添加了listview标记,您想在哪个事件中找到控件?@Damith在代码后面的按钮单击事件中。
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
        }
    }
}
    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;
    }