【问题标题】:Returning "full" clientID in code behind (asp.net VB)在后面的代码中返回“完整”clientID(asp.net VB)
【发布时间】:2012-08-08 03:07:03
【问题描述】:

所以我在访问 ASP.NET 用户控件的正确 clientID 属性时遇到了问题。

我的主要问题是我正在尝试使用 VB 代码隐藏返回控件的完整 ClientID 字段。我的控件的预期值(以及浏览器中显示的值)是:

  • ctl00_ContentPlaceHolder1_ctl05_txtAnswer

但我只在代码隐藏中得到“txtAnswer”。

我在这里找到了类似的东西:

ASP.Net: ClientID not correct in code-behind of a user control

这篇文章建议在onPreRender或onPageLoad等期间添加onClick事件,但我还有其他情况:

  • 我的用户控件(文本框)旨在“预加载”数据库中的值(如果同一用户之前曾尝试访问该表单),或者如果 isPostBack == true。

  • 因为我正在从数据库中读取答案,并且因为有 JS 函数(它使用 getElementByID() JS 函数),所以控件需要访问用户数据...

  • 目前该控件有一个成员函数loadQuestions(key parameters),可以从数据库中加载特定的问题。

  • 更多上下文:我正在更新一些具有硬编码(在客户端 ASPX 文件中)控件元素的旧代码,但现在控件是在运行时动态构建的(即,插入到客户端页面中的占位符中) )。

  • 我尝试过使用不同的 ClientIDMode 设置(每个 http://msdn.microsoft.com/en-us/library/system.web.ui.clientidmode.aspx),但到目前为止没有骰子...我使用的是 .NET 4.0,所以我知道我可以通过“静态”直接编辑 ClientID " clientIDmode,不过我还没试过……

现在我在想我应该将所有定义内容的东西“预先加载”到对象的构造函数中,然后应用所有定义内容的东西,然后在控件之后建立 onClick 属性数据已填充?

供参考:

这是控件的 ASP 标记:

<%@ Control Language="VB" AutoEventWireup="false" CodeFile="RBHorizWithText.ascx.vb" Inherits="Apps_Controls_RBHorizWithText" %>
<%@ Register Assembly="txtBoxLengthValidator" Namespace="txtBoxLengthValidator" TagPrefix="cc1" %>

<asp:Panel ID="pnlPreamble" runat="server">
    <div id="divPreamble" runat="server" style="padding-bottom:15px"></div>
</asp:Panel>

<asp:Panel ID="pnlQuestion" runat="server">
    <div id="divQuestion1" runat="server"></div>



    <div id="divRBL" runat="server"  style="padding-left: 20px"> 
      <asp:Table ID="tblAnswers" runat="server" CellPadding="0" CellSpacing="0">
      </asp:Table>
    </div>

    <div id="divQuestion2" runat="server" style="padding-left: 20px; padding-top: 10px"></div>
    <div id="divAnswer2" runat="server" style="padding-left:20px; padding-top: 5px; text-align: left" align="left">
        <div>
            <cc1:TextBoxLengthValidator 
                ID="tblvAnswer" 
                    ControlToValidate="txtAnswer" 
                    runat="server" 
                    ErrorMessage="Maximum length is 255 Characters" 
                    MaximumLength="255" 
                    Display="Dynamic"
                    ForeColor="Red">
            </cc1:TextBoxLengthValidator>    
        </div>

        <div><asp:TextBox ClientIDMode = "Predictable" ID = "txtAnswer" runat="server" Width="600px" Rows="3" TextMode="MultiLine"></asp:TextBox></div>

    </div>

</asp:Panel>

这里是调用 JS 函数的 VB 代码隐藏函数(为简洁而编辑)...

Public Sub LoadQuestions(ByVal objQRBL As Question, ByVal objQText As Question, ByVal dicAnswers As Dictionary(Of Integer, QuestionAnswer), ByVal LoadAnswers As Boolean)
        'This is a function from RBHorizWithText user control that has two member controls: a radio button and a text box (first 2 params).
        'dicAnswers are the user's answers stored either in HttpContext.Current, or as global memory objects...


        _lstRadioButtons = New List(Of RadioButton)
        Me.tblAnswers.Rows.Clear()
        'txtAnswer is a member control of type textBox...
        Me.txtAnswer.Text = String.Empty

        '.
        'Stuff to build out <tr> and <td> question display elements to format/store control...
        '.


        Dim trw As New TableRow
        Dim iCount As Integer = 0

        For Each objA As QuestionAnswer In objQRBL.AnswerList           

            Dim objRB As New RadioButton

            objRB.ID = objA.QuestID & ";" & objA.AnswerID
            objRB.GroupName = "rb" & objA.QuestID
            objRB.Text = objA.AnswerText

            'This is the main area where I'm having trouble:  
            '   At runtime, Me.txtAnswer.ClientID should evaluate to: "ctl00_ContentPlaceHolder1_ctl05_txtAnswer"
            '   Instead I'm getting:    "txtAnswer"

            If objQText.ParentReqResponseCode.IndexOf(";" & objA.ResponseCode & ";") <> -1 Then
                objRB.Attributes.Add("onclick", "txtBoxEnable('" & Me.txtAnswer.ClientID & "');")
            Else
                objRB.Attributes.Add("onclick", "txtBoxDisable('" & Me.txtAnswer.ClientID & "','" & objQText.InnerText & "');")
            End If


            tcl.Controls.Add(objRB)
            trw.Cells.Add(tcl)

            _lstRadioButtons.Add(objRB)

            iCount += 1
        Next

        'Other stuff to handle formatting and behavior of other controls...

    End Sub

以下是 JS 函数,它们存在于项目的母版页上:

function txtBoxEnable(elID) {                     
    var el = document.getElementById(elID);
    el.style.backgroundColor = '#f4df8d';
    el.value = '';
    el.disabled = '';           
}

function txtBoxDisable(elID, innerText) {
    var el = document.getElementById(elID);
    el.value = innerText;
    el.style.backgroundColor = '#ffffff';
    el.disabled = 'disabled';
}

非常感谢! -刘易斯

【问题讨论】:

    标签: javascript asp.net vb.net clientid


    【解决方案1】:

    我尝试过使用不同的 ClientIDMode 设置(每 http://msdn.microsoft.com/en-us/library/system.web.ui.clientidmode.aspx) 但到目前为止还没有骰子......我正在使用.NET 4.0,所以我知道我可以 通过“静态”clientIDmode直接编辑ClientID,我没有 不过试过了...

    试试吧,它会彻底解决你的问题。您在标记上分配的任何 ID 都将是您在服务器端检索到的 ID。 ID 前面没有额外的垃圾。

    【讨论】:

    • 谢谢!试过这个并且大部分都有效,但我遇到了一个错误,该函数仅启用了此控件的第一个实例。我希望这意味着如果页面上有多个相同类型的控件,只需要使用代码隐藏来确保每个 ID 属性都是唯一的?
    • 是的,只需要为每个文本框控件动态生成/设置 ID 属性。再次感谢。
    猜你喜欢
    • 2018-01-28
    • 2016-09-27
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    • 2011-05-23
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    相关资源
    最近更新 更多