ASP.NET:GridView内DropDownList与TextBox绑定同DataTable无回发联动
解决方案:GridView内DropDownList与TextBox无回发绑定及实时计算
1. 调整GridView模板列结构
在ASPX页面中定义包含目标控件的模板列,通过CSS类统一标识控件,方便JavaScript定位:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" OnRowDataBound="GridView1_RowDataBound"> <Columns> <!-- 其他业务列 --> <asp:TemplateField HeaderText="物料选择"> <ItemTemplate> <asp:DropDownList ID="ddlMaterial" runat="server" CssClass="ddlMaterial"></asp:DropDownList> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="换算系数"> <ItemTemplate> <asp:TextBox ID="txtMul" runat="server" CssClass="txtMul" ReadOnly="True"></asp:TextBox> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="数量"> <ItemTemplate> <asp:TextBox ID="txtQty" runat="server" CssClass="txtQty"></asp:TextBox> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="总重量"> <ItemTemplate> <asp:TextBox ID="txtTotalWeight" runat="server" CssClass="txtTotalWeight" ReadOnly="True"></asp:TextBox> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView>
2. 后台RowDataBound事件绑定数据并存储系数
在VB.NET后台的RowDataBound事件中,为每行的DropDownList单独绑定数据源,并将Multiplier值存入列表项的自定义属性:
Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound If e.Row.RowType = DataControlRowType.DataRow Then Dim ddlMaterial As DropDownList = DirectCast(e.Row.FindControl("ddlMaterial"), DropDownList) ' 替换为你的DataTable获取逻辑(比如从数据库查询) Dim dtMaterial As DataTable = GetMaterialData() ddlMaterial.DataSource = dtMaterial ddlMaterial.DataTextField = "EName" ddlMaterial.DataValueField = "Id" ddlMaterial.DataBind() ' 给每个列表项添加data-multiplier属性,存储换算系数 For Each item As ListItem In ddlMaterial.Items Dim targetRow As DataRow = dtMaterial.Select($"Id = {item.Value}")(0) item.Attributes("data-multiplier") = targetRow("Multiplier").ToString() Next ' 初始化默认选中项的系数值 If ddlMaterial.Items.Count > 0 Then Dim txtMul As TextBox = DirectCast(e.Row.FindControl("txtMul"), TextBox) txtMul.Text = ddlMaterial.Items(0).Attributes("data-multiplier") ' 初始计算总重量 CalculateRowTotal(e.Row) End If End If End Sub ' 示例:获取物料DataTable的方法 Private Function GetMaterialData() As DataTable Dim dt As New DataTable() dt.Columns.Add("Id", GetType(Integer)) dt.Columns.Add("EName", GetType(String)) dt.Columns.Add("Multiplier", GetType(Decimal)) ' 测试数据,替换为实际业务数据 dt.Rows.Add(1, "Steel Plate", 7.85) dt.Rows.Add(2, "Aluminum Bar", 2.7) dt.Rows.Add(3, "PVC Pipe", 1.38) Return dt End Function ' 后台初始化计算行总重量 Private Sub CalculateRowTotal(row As GridViewRow) Dim txtMul As TextBox = DirectCast(row.FindControl("txtMul"), TextBox) Dim txtQty As TextBox = DirectCast(row.FindControl("txtQty"), TextBox) Dim txtTotal As TextBox = DirectCast(row.FindControl("txtTotalWeight"), TextBox) Dim mul As Decimal = If(Decimal.TryParse(txtMul.Text, mul), mul, 0) Dim qty As Decimal = If(Decimal.TryParse(txtQty.Text, qty), qty, 0) txtTotal.Text = (mul * qty).ToString("F2") End Sub
3. JavaScript实现无回发实时更新与计算
在页面底部引入jQuery(适配.NET 4.0环境的1.x版本),编写事件监听逻辑:
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script> <script> $(function() { // 监听下拉框切换事件 $(".ddlMaterial").change(function() { var $row = $(this).closest("tr"); var selectedMultiplier = $(this).find("option:selected").data("multiplier"); // 更新系数文本框 $row.find(".txtMul").val(selectedMultiplier); // 计算总重量 updateTotal($row); }); // 监听数量输入事件 $(".txtQty").on("input", function() { var $row = $(this).closest("tr"); updateTotal($row); }); // 计算并更新总重量的核心函数 function updateTotal($row) { var multiplier = parseFloat($row.find(".txtMul").val()) || 0; var quantity = parseFloat($row.find(".txtQty").val()) || 0; var total = multiplier * quantity; $row.find(".txtTotalWeight").val(total.toFixed(2)); } }); </script>
核心逻辑说明
- 由于GridView无法直接绑定目标DataTable,通过
RowDataBound为每行单独绑定DropDownList,并利用HTML自定义属性data-multiplier存储系数值,避免回发即可获取数据。 - 将
txtMul设置为只读,确保系数值始终与下拉框选中项同步,防止用户手动修改导致数据不一致。 - 利用jQuery的DOM遍历能力,定位当前行的所有关联控件,实现纯前端的实时计算,全程无服务器回发。
内容的提问来源于stack exchange,提问作者Syed Asif ali
相关产品推荐
相关产品推荐

