65.9K
CodeProject 正在变化。 阅读更多。
Home

如何:在 GridView 中执行计算

starIconstarIconstarIconstarIconstarIcon

5.00/5 (6投票s)

2016 年 7 月 13 日

CPOL

3分钟阅读

viewsIcon

21937

downloadIcon

384

一个简单的演示,解释了如何使用 JavaScript 在 GridView 中进行计算。

引言

我在各种论坛上看到许多刚入门的开发人员努力在 GridView 中实现简单的计算。通常,他们想在 TextBox 控件中输入值时计算总金额,并在页脚显示总计值。您可能已经知道,这可以使用服务器端方法轻松完成。

让我们快速回顾一下如何实现服务器端方法的计算。假设我们有以下 GridView 标记。

服务器端方法

假设我们有以下 GridView 标记

<asp:GridView ID="GridView1" runat="server" 
AutoGenerateColumns="false" ShowFooter="true">  
  <Columns>  
     <asp:BoundField DataField="ItemDescription" HeaderText="Item"/>  
     <asp:TemplateField HeaderText="Amount">  
       <ItemTemplate>  
         <asp:TextBox ID="TextBox1" runat="server"   
                      AutoPostBack="True"  
                      ontextchanged="TextBox1_TextChanged">    
         </asp:TextBox>  
       </ItemTemplate>  
     </asp:TemplateField>  
  </Columns>  
</asp:GridView>  

上面的标记非常简单。一个 GridView,包含一个 BoundField 列用于显示项目,以及一个 TemplateField 列用于金额列。现在,让我们使用 ADO.NET 方式从数据库中填充网格数据。以下是代码块

private string GetConnectionString(){  
        //Where MYDBConnection is the connetion string that was set up from the web config file  
        return System.Configuration.ConfigurationManager.ConnectionStrings
        ["MyDBConnection"].ConnectionString;  
}
  
// Method for Binding the GridView Control  
private void BindGridView(){  
    using (SqlConnection connection = new SqlConnection(GetConnectionString())) {  
            string sql = "SELECT * FROM YourTable";  
            using (SqlCommand cmd = new SqlCommand(sql, connection)) {  
                    connection.Open();  
                    using(var adapter = new SqlDataAdapter(cmd)){  
                          adapter.Fill(dt)  
                          if (dt.Rows.Count > 0){  
                               GridView1.DataSource = dt;  
                               GridView1.DataBind();  
                          }  
                    }  
           }  
    }  
}
  
//Bind GridView on initial postabck  
protected void Page_Load(object sender, EventArgs e){  
        if (!Page.IsPostBack)  
            BindGridView();   
}  

以下是计算总计的代码块

//Calculate the Totals in the TextBox rows  
protected void TextBox1_TextChanged(object sender, EventArgs e){  
        double total = 0;  
        foreach (GridViewRow gvr in GridView1.Rows)  
        {  
            TextBox tb = (TextBox)gvr.Cells[1].FindControl("TextBox1");  
            double sum;  
            if(double.TryParse(tb.Text.Trim(),out sum))  
            {  
                total += sum;  
            }  
        }  
        //Display  the Totals in the Footer row  
        GridView1.FooterRow.Cells[1].Text = total.ToString();  
}  

这很简单!运行代码现在将为您提供一个启用了总金额计算的网格。现在,在某些情况下,您可能需要实现客户端计算,无论出于何种原因。在本文中,我们将看看如何实现它。请记住,服务器端方法实际上并不适合执行此类操作,因为每次在 TextBox 中更改/键入值时,TextChanged 事件都会触发服务器回发。

使用 JavaScript 的客户端方法

要开始,让我们设置表单。为简单起见,让我们这样设置表单

<asp:gridview ID="GridView1"  runat="server"  
ShowFooter="true" AutoGenerateColumns="false">  
    <Columns>  
        <asp:BoundField DataField="RowNumber" HeaderText="Row Number" />  
        <asp:BoundField DataField="Description" HeaderText="Item Description" />  
        <asp:TemplateField HeaderText="Item Price">  
            <ItemTemplate>  
                <asp:Label ID="LBLPrice" runat="server" 
                Text='<%# Eval("Price","{0:C}") %>'></asp:Label>  
            </ItemTemplate>  
            <FooterTemplate>  
                <b>Total Qty:</b>  
            </FooterTemplate>  
        </asp:TemplateField>  
        <asp:TemplateField HeaderText="Quantity">  
            <ItemTemplate>  
                <asp:TextBox ID="TXTQty" runat="server" 
                onkeyup="CalculateTotals();"></asp:TextBox>  
            </ItemTemplate>  
            <FooterTemplate>  
                <asp:Label ID="LBLQtyTotal" runat="server" 
                Font-Bold="true" ForeColor="Blue" Text="0" ></asp:Label>       
                <b>Total Amount:</b>  
            </FooterTemplate>  
        </asp:TemplateField>  
        <asp:TemplateField HeaderText="Sub-Total">  
            <ItemTemplate>  
                <asp:Label ID="LBLSubTotal" runat="server" 
                ForeColor="Green" Text="0.00"></asp:Label>  
            </ItemTemplate>  
            <FooterTemplate>  
                <asp:Label ID="LBLTotal" runat="server" 
                ForeColor="Green" Font-Bold="true" Text="0.00"></asp:Label>  
            </FooterTemplate>  
        </asp:TemplateField>  
    </Columns>  
</asp:gridview> 

如您所见,上面的标记实际上没有什么特别之处。它只包含一个标准的 GridView,上面有 BoundFieldsTemplateFields。仅为了演示的目的,我将使用虚拟数据来填充 GridView。以下是代码块

public partial class GridCalculation : System.Web.UI.Page  
{  
        private void BindDummyDataToGrid() {  
  
            DataTable dt = new DataTable();  
            DataRow dr = null;  
  
            dt.Columns.Add(new DataColumn("RowNumber", typeof(int)));  
            dt.Columns.Add(new DataColumn("Description", typeof(string)));  
            dt.Columns.Add(new DataColumn("Price", typeof(string)));  
  
            dr = dt.NewRow();  
            dr["RowNumber"] = 1;  
            dr["Description"] = "Nike";  
            dr["Price"] = "1000";  
            dt.Rows.Add(dr);  
  
            dr = dt.NewRow();  
            dr["RowNumber"] = 2;  
            dr["Description"] = "Converse";  
            dr["Price"] = "800";  
            dt.Rows.Add(dr);  
  
            dr = dt.NewRow();  
            dr["RowNumber"] = 3;  
            dr["Description"] = "Adidas";  
            dr["Price"] = "500";  
            dt.Rows.Add(dr);  
  
            dr = dt.NewRow();  
            dr["RowNumber"] = 4;  
            dr["Description"] = "Reebok";  
            dr["Price"] = "750";  
            dt.Rows.Add(dr);  
            dr = dt.NewRow();  
            dr["RowNumber"] = 5;  
            dr["Description"] = "Vans";  
            dr["Price"] = "1100";  
            dt.Rows.Add(dr);  
            dr = dt.NewRow();  
            dr["RowNumber"] = 6;  
            dr["Description"] = "Fila";  
            dr["Price"] = "200";  
            dt.Rows.Add(dr);  
           //Bind the GridView  
            GridView1.DataSource = dt;  
            GridView1.DataBind();  
        }  

        protected void Page_Load(object sender, EventArgs e) {  
            if (!IsPostBack)  
                BindDummyDataToGrid();  
        }  
}

运行页面应该会得到类似这样的结果

请记住,客户端实现方式是完全不同的,因为您需要处理 DOM 元素来提取控件,并且您需要理解 JavaScript 语法,与使用 C# 的服务器端实现相比,这有点复杂。现在让我们进入这个演示的“”,即客户端计算的实现。主要功能包括以下内容

  • 数字验证
  • 将值格式化为带有分隔符的可读货币格式
  • 小计和总金额的计算

这是 JavaScript 代码(这应该放在 WebForm 页面的 <head> 部分内)

<script type="text/javascript">  
        
        function CalculateTotals() {  
            var gv = document.getElementById("<%= GridView1.ClientID %>");  
            var tb = gv.getElementsByTagName("input");  
            var lb = gv.getElementsByTagName("span");  
  
            var sub = 0;  
            var total = 0;  
            var indexQ = 1;  
            var indexP = 0;  
            var price = 0;  
  
            for (var i = 0; i < tb.length; i++) {  
                if (tb[i].type == "text") {  
                    ValidateNumber(tb[i]);  
  
                    price = lb[indexP].innerHTML.replace
                    ("$", "").replace(",", "");  
                    sub = parseFloat(price) * parseFloat(tb[i].value);  
                    if (isNaN(sub)) {  
                        lb[i + indexQ].innerHTML = "0.00";  
                        sub = 0;  
                    }  
                    else {  
                        lb[i + indexQ].innerHTML = 
                        FormatToMoney(sub, "$", ",", "."); ;  
                    }  
                     
                    indexQ++;  
                    indexP = indexP + 2;  
  
                    total += parseFloat(sub);  
                }  
            }  
  
            lb[lb.length - 1].innerHTML = 
            FormatToMoney(total, "$", ",", ".");  
        }  
  
        function ValidateNumber(o) {  
            if (o.value.length > 0) {  
                o.value = o.value.replace(/[^\d]+/g, ''); //Allow only whole numbers  
            }  
        } 
 
        function isThousands(position) {  
            if (Math.floor(position / 3) * 3 == position) return true;  
            return false;  
        };  
  
        function FormatToMoney(theNumber, theCurrency, theThousands, theDecimal) {  
            var theDecimalDigits = Math.round((theNumber * 100) - (Math.floor(theNumber) * 100));  
            theDecimalDigits = "" + (theDecimalDigits + "0").substring(0, 2);  
            theNumber = "" + Math.floor(theNumber);  
            var theOutput = theCurrency;  
            for (x = 0; x < theNumber.length; x++) {  
                theOutput += theNumber.substring(x, x + 1);  
                if (isThousands(theNumber.length - x - 1) && (theNumber.length - x - 1 != 0)) {  
                    theOutput += theThousands;  
                };  
            };  
            theOutput += theDecimal + theDecimalDigits;  
            return theOutput;  
        }   
</script> 

让我们尝试评估上面的每个 JavaScript 函数。FormatToMoney() 是一个函数,它通过传递数值、货币、千位分隔符和小数分隔符来将数值格式化为货币。isThousand() 函数评估该值并返回 Boolean。此函数在 FormatToMoney() 函数中使用,以确定该值是否为千位。ValidateNumber() 是一个函数,用于验证提供的值是否为有效数字。最后,CalculateTotals() 是一个主函数,它从 GridView 中提取每个元素,计算值并将计算后的值设置回 GridView 元素,在本例中是小计和总金额。

现在,像这样在“onkeyup”或“onkeypress”事件中调用 JavaScript CalculateTotals() 函数

<ItemTemplate>  
     <asp:TextBox ID="TXTQty" runat="server" onkeyup="CalculateTotals();"></asp:TextBox> 
</ItemTemplate> 

运行页面将为您提供以下输出。

初始加载时

TextBox 中输入值后

就这样!我希望有人觉得这篇文章有用。

© . All rights reserved.