繁体   English   中英

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

[英]Locate control in asp:listview when I have the clientid for the control?

  • VS2012,.NET 4.51,WebForms

从后面代码中的单击事件中,我获得了ItemTemplate中控件的客户端ID(自然地,该控件是为listview中的每个记录创建的):

var lastControlWithFocusClientId = "cphContainer_ucTakeTest_lvData_txtAnswer_0";

我需要找到该控件,所以我尝试了:

lvData.FindControl(lastControlWithFocusClientId)

Page.FindControl(lastControlWithFocusClientId) 

但是,两者都返回null(即找不到控件。)那么,我在这里缺少什么?

EDIT 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属性

http://msdn.microsoft.com/zh-cn/library/system.web.ui.control.clientidmode%28v=vs.110%29.aspx

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

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

因此,如果我在该行中有一个LinkBut​​ton,并且有一个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;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM