ASP.NET中TextBox扫描条码后立即触发TextChanged事件的实现问题
解决方案:实现扫描条码后立即触发后台操作
核心问题分析
默认情况下,ASP.NET的TextBox控件的TextChanged事件(搭配AutoPostBack="true")仅在控件失去焦点时触发,而扫描枪输入条码的过程是一次性完成的,不会主动让控件失去焦点,因此无法即时触发后台代码。
方案1:利用扫描枪的回车键触发即时回发
绝大多数扫描枪支持配置为扫描完成后自动发送回车键(Enter),我们可以通过捕获这个按键直接触发回发,无需等待控件失焦。
1. 修改前端TextBox代码
<asp:TextBox ID="txtSKU3" ontextchanged="txtSKU3_TextChanged" AutoPostBack="true" ToolTip="SKU" ForeColor="Red" placeholder="SKU" Height="30px" CssClass="form-control input-sm" runat="server" onkeypress="return checkEnter(event);"></asp:TextBox> <script type="text/javascript"> function checkEnter(e) { e = e || window.event; // 捕获回车键(keyCode=13) if (e.keyCode === 13) { // 调用ASP.NET内置回发函数,触发TextBox的TextChanged事件 __doPostBack('<%= txtSKU3.UniqueID %>', ''); return false; // 阻止默认回车行为(比如换行) } return true; } </script>
2. 优化后台代码(可选)
为了避免重复添加条码图片,每次触发时先清空容器,同时清空TextBox方便下一次扫描:
protected void txtSKU3_TextChanged(object sender, EventArgs e) { string barCode = txtSKU3.Text.Trim(); if (string.IsNullOrEmpty(barCode)) return; // 清空之前的条码图片 PlaceHolder1.Controls.Clear(); System.Web.UI.WebControls.Image imgBarCode = new System.Web.UI.WebControls.Image(); using (Bitmap bitMap = new Bitmap(barCode.Length * 40, 80)) { using (Graphics graphics = Graphics.FromImage(bitMap)) { Font oFont = new Font("IDAutomationHC39M", 16); PointF point = new PointF(2f, 2f); SolidBrush blackBrush = new SolidBrush(Color.Black); SolidBrush whiteBrush = new SolidBrush(Color.White); graphics.FillRectangle(whiteBrush, 0, 0, bitMap.Width, bitMap.Height); graphics.DrawString("*" + barCode + "*", oFont, blackBrush, point); } using (MemoryStream ms = new MemoryStream()) { bitMap.Save(ms, System.Drawing.Imaging.ImageFormat.Png); byte[] byteImage = ms.ToArray(); imgBarCode.ImageUrl = "data:image/png;base64," + Convert.ToBase64String(byteImage); } PlaceHolder1.Controls.Add(imgBarCode); // 清空TextBox,准备下一次扫描 txtSKU3.Text = string.Empty; } }
方案2:使用UpdatePanel实现局部无刷新触发
如果需要避免整个页面回发的闪烁感,可以结合UpdatePanel实现局部刷新:
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:TextBox ID="txtSKU3" ontextchanged="txtSKU3_TextChanged" AutoPostBack="true" ToolTip="SKU" ForeColor="Red" placeholder="SKU" Height="30px" CssClass="form-control input-sm" runat="server" onkeypress="return checkEnter(event);"></asp:TextBox> <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="txtSKU3" EventName="TextChanged" /> </Triggers> </asp:UpdatePanel> <script type="text/javascript"> function checkEnter(e) { e = e || window.event; if (e.keyCode === 13) { __doPostBack('<%= txtSKU3.UniqueID %>', ''); return false; } return true; } </script>
关键注意事项
- 扫描枪配置:如果扫描枪没有自动发送回车键,需要进入扫描枪的设置模式开启该功能(参考对应扫描枪的说明书)。
__doPostBack:ASP.NET内置的回发函数,通过传入控件的UniqueID可以精准触发目标控件的服务器事件。
内容的提问来源于stack exchange,提问作者Raja
相关产品推荐
相关产品推荐

