当我拥有控件的clientid时,在asp:listview中找到控件?

时间:2014-01-17 02:31:04

标签: c# listview webforms

  • VS2012,.NET 4.51,WebForms

从后面代码中的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>

3 个答案:

答案 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时,我最终会获取触发该行事件的控件。

因此,如果我在行中有一个LinkBut​​ton,并且我有一个点击事件,我将执行以下操作

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;
    }