【问题标题】:WebForms Textbox.TextChanged event is firing twice on button clickWebForms Textbox.TextChanged 事件在按钮单击时触发两次
【发布时间】:2021-04-12 16:47:40
【问题描述】:

似乎有一百个问题非常相似,但似乎没有一个可以解决我的问题。

我有一个非常基本的引导网络表单,其中包含两个文本框 - 每个文本框都接受一个序列号,该序列号由连接到 PC 的手持扫描仪填充。当用户扫描第一个条形码时,txtLabelA 的 TextChanged 事件会触发一个验证序列号并将焦点切换到 txtLabelB 的方法。当用户扫描第二个条形码时,它会触发 txtLabelB 的 TextChanged 事件。这会将两个值插入数据库中的交叉引用表中,显示成功消息并清除下一组序列号的表单。非常直截了当。这在很长一段时间内都完美无缺。

但是,最近我被要求在表单中添加一个按钮,允许用户手动输入序列号并单击提交。现在一切都搞砸了,因为单击提交按钮会触发 OnClick AND OnTextChanged 事件,从而导致表单回发两次。我怎样才能防止这种情况发生?

<div class="card-body">
            <div class="form-group">                    
                <asp:TextBox ID="txtLabelA" runat="server" EnableViewState="true" CssClass="form-control" AutoPostBack="true" OnTextChanged="txtLabelA_TextChanged"></asp:TextBox>
                <span class="help-block"></span>
            </div>               
            <div class="form-group">
                <asp:TextBox ID="txtLabelB" runat="server" EnableViewState="true" CssClass="form-control" AutoPostBack="true" OnTextChanged="txtLabelB_TextChanged"></asp:TextBox>
                <span class="help-block"></span>
            </div>
            <div class="form-group">
                <asp:Button ID="btnSubmit" runat="server" Text="Submit" CssClass="btn btn-primary" OnClick="btnSubmit_Click" />
                <asp:Button ID="btnCancel" runat="server" Text="Clear" CssClass="btn btn-secondary" OnClick="btnCancel_Click" />
                <div style="margin-top: 10px;">
                    <p>
                        <asp:Label ID="lblError" runat="server" CssClass="text-danger"></asp:Label>
                        <asp:Label ID="lblSuccess" runat="server" CssClass="text-success"></asp:Label>
                    </p>
                </div>
            </div>
        </div>

这是后面代码的 sn-p(不多):

 protected void txtLabelA_TextChanged(object sender, EventArgs e)
    {
        GetLabelDetails();
    }
 protected void txtLabelB_TextChanged(object sender, EventArgs e)
    {
        SyncLabels();
    }

 protected void btnSubmit_Click(object sender, EventArgs e)
    {
        SyncLabels();
    }

我什至尝试将按钮的 OnClick 事件更改为 OnTextChanged 事件,但没有帮助。

有人有什么想法吗?

谢谢。

【问题讨论】:

  • SyncLabels() 方法是否会改变 txtLabelB 的文本?如果是这样,由于您正在触发 btnSubmit_Click(),我假设它会更改 txtLabelB 中的文本,然后它会触发您的 _TextChanged() 事件,从而导致双重回发。只是想在进一步回答之前得到澄清。
  • 实际上,如果成功,SyncLabels() 会调用 ClearForm() 方法,该方法会将两个文本框重置回 string.Empty()。这可能是其中的一部分。但具有讽刺意味的是, OnTextChanged 事件也会清除两个文本框。既然你提到它,我想知道为什么不点击提交按钮就不会触发它。
  • 也许您可以调用一个函数,该函数只更改文本框的文本并阻止按钮从 AutoPostBack 以防止双重 AutoPostBack,但依赖于 _TextChanged() 事件。
  • 不确定这是否是“正确”的解决方案,也许有点笨拙,但它就像一个魅力!

标签: c# webforms autopostback


【解决方案1】:

好的,伙计们,我们找到了解决方案。我合并了上面两张海报的建议以找到解决方案。我从 Daniel 的建议开始,在按钮的单击事件中不添加任何内容,以确保它不会触发 SyncLabels() 方法,但仅此一项并不能完全解决它,因为事件本身仍在导致回发。诀窍是在上面包含 Bmils 的注释,以向按钮的 OnClientCLick() 事件添加一个无意义的 JavaScript 函数。这使我能够“返回:false;”,有效地阻止了客户端的第二次回发。谢谢你们的意见。如果有你的帮助,我不会解决这个问题。

【讨论】:

    【解决方案2】:

    https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.webcontrols.textbox.autopostback?view=netframework-4.8

    使用 AutoPostBack 属性指定当 TextBox 控件失去焦点时是否会自动回发到服务器。在 TextBox 控件中按 ENTER 或 TAB 键是更改焦点的最常用方法。

    根据我的个人经验,条形码扫描仪本质上是模仿用户输入条形码编号然后按 ENTER 键。如果用户手动输入条形码编号,然后单击“提交”按钮,则 TextBox 无论如何都会失去焦点并导致额外的回发。

    建议:删除 Button.Click 事件(或至少删除 Click 处理程序中的逻辑。)

    注意:如果 TextBox 控件的父容器包含标记为默认按钮的按钮(例如,如果设置了容器的 DefaultButton 或 DefaultButton 属性),则不会引发默认按钮的 Click 事件以响应自动回发。

    【讨论】:

    • 是的,您的经验是正确的。扫描仪被配置为输入文本并模拟 TAB 键击。这(失去焦点)是触发 TextChanged 事件的原因。我尝试简单地从 OnClick 事件中删除代码,希望它允许 TextChanged 事件触发同步过程,但它没有帮助。所以然后我尝试完全删除 Click 事件,使按钮没有附加任何操作,使其基本上是一个虚拟按钮。起初这似乎可行,但由于某种原因它正在更新数据库,但在回发后无法处理任何内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-27
    • 2011-01-08
    • 1970-01-01
    • 1970-01-01
    • 2014-08-08
    • 1970-01-01
    相关资源
    最近更新 更多