创建一个使用我给它的 ID 并遵循 ClientIDMode="Static" 的自定义用户控件

Create a Custom User Control that Uses the ID I give it and honors ClientIDMode="Static"

我有一些用 C# 为我的 Web 应用程序构建的自定义控件。我也在使用 Visual Studio 2013.

控制:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="YearsTextBox.ascx.cs" Inherits="MutualExpert.Controls.YearsTextBox"  %>
<div class="input-group">
    <asp:TextBox ID="tb" runat="server" CssClass="form-control text-right" />
    <div class="input-group-addon">Years</div>
</div>

从 ASPX 页面调用它我想在以下位置使用它:

<cc:YearsTextBox runat="server" ID="tbDamageLife" />

我希望控件在页面上呈现为 "tbDamageLife"

我试过的:

如果我指定 ClientIDMode="Static" 然后我得到 ID="tb" :

<div class="input-group">
    <input name="ctl00$cpMain$tbDamageLife$tb" id="tb" class="form-control text-right" type="text">
    <div class="input-group-addon">Years</div>
</div>

如果我不这样做,我会得到 ID="ctl00_cpMain_tbDamageLife_tb" :

<div class="input-group">
    <input name="ctl00$cpMain$tbDamageLife$tb" id="ctl00_cpMain_tbDamageLife_tb" class="form-control text-right" type="text">
    <div class="input-group-addon">Years</div>
</div>

我只是想让它渲染 tbDamageLife,我给它的 ID。

这是一个棘手的问题,我需要这些是静态的以便 JS 访问它来进行计算。有必要。如果可以的话,我会解决它,但我就是做不到。

UserControl 本身在 html 中没有 ID,只有在代码中。因此,在您的情况下,最好的解决方案是将 UserControl 内容包装在面板中并为其提供 ID tbDamageLife。那将成为 <div> 与 class input-group.

<asp:Panel ID="tbDamageLife" runat="server" CssClass="input-group">
    <asp:TextBox ID="tb" runat="server" CssClass="form-control text-right" />
    <div class="input-group-addon">Years</div>
</asp:Panel>

在父页面上

<cc:YearsTextBox runat="server" ID="tbDamageLife" ClientIDMode="Static" />

将呈现为

<div id="tbDamageLife" class="input-group">
    <input name="ctl00$cpMain$tbDamageLife$tb" type="text" id="tb" class="form-control text-right" />
    <div class="input-group-addon">Years</div>
</div>

但是,如果您要添加多个控件,您将拥有重复的 ID。

或者如果您不需要面板控制的功能,您可以简单地执行以下操作。

<div id="tbDamageLife" class="input-group">
    <asp:TextBox ID="tb" runat="server" CssClass="form-control text-right" />
    <div class="input-group-addon">Years</div>
</div>

用户控件充当 "placeholder" 并在呈现调用页面时由其实际内容替换:

<form method="post" id="form1">
    <div class="input-group">
        <input name="tbDamageLife$tb" type="text" id="tbDamageLife_tb" class="form-control text-right">
        <div class="input-group-addon">Years</div>
    </div>
</form>

在上面的示例中,请注意没有具有 tbDamageLife id 的元素。相反,用户控件 id 用于为包含的 TextBox(已呈现)生成唯一标识。所以,这是非常标准的行为,也是正确的行为。

不过,您可以使用 ClientID 从 javascript 访问用户控件的 TextBox,例如:

<form id="form1" runat="server">
    <div>
        <uc:YearsTextBox runat="server" ID="tbDamageLife" />
        <input type="button" value="OK" onclick="btnOK_Click()" />
    </div>
</form>
<script type="text/javascript">
    function btnOK_Click() {
        var ucTb = document.getElementById('<%= tbDamageLife.FindControl("tb").ClientID %>');

        console.log(ucTb.value);
    }
</script>

恕我直言,这是 "safest" 的方式,这意味着您实际上是在使用来自服务器代码的 tbDamageLife id, 确实知道 关于它。

我和团队找到了另一种方法,最终在 HTML 和 JS 方面的代码少了很多,恕我直言,团队更容易记住和使用它。

简单来说就是加一个CSSclass的名字。示例:

<cc:YearsTextBox runat="server" ID="tbDamageLife" CssClass="tbDamageLife" />

在用户控件中:

    /// <summary>
    /// Gets or sets Class
    /// </summary>
    public string CssClass
    {
        get { return tb.CssClass; }
        set
        {
            // we need to make sure that form-control is always part of the Class
            if (value.Contains("form-control"))
                tb.CssClass = value;
            else
                tb.CssClass += " " + value;
        }
    }

在 JS 中:

    case _ui.newlevel.select:
        $(".tbDamageLife").removeAttr("disabled");