如何将gridview列相乘并在另一列中显示该列

时间:2015-02-11 05:15:21

标签: c# asp.net gridview

我想在gridview中将gridview列与一个Label和Textbox控件相乘,并在另一列中显示相乘的值,如图所示。我想要做的是,一旦我点击按钮,所有项目都显示在gridview上,如下所示,然后它将自动乘以相应列中的* 1(默认数量为1)。

我的asp.net代码

 <%--ServiceID --%>
<asp:TemplateField HeaderText="ServiceID" ItemStyle-Width="100px">
<ItemTemplate>
      <asp:Label ID="lblServiceID" runat="server" Text='<%# Eval("ServiceId")%>'></asp:Label>
</ItemTemplate>
<ItemStyle Width="100px" />
</asp:TemplateField>

<%-- Rate --%>
<asp:TemplateField HeaderText="Rate" ItemStyle-Width="70px">
<ItemTemplate>
    <asp:Label ID="lblRate" runat="server" Text='<%# Eval("Rate")%>' CssClass="rate"></asp:Label>
</ItemTemplate>       
<ItemStyle Width="70px" />
</asp:TemplateField>

<%-- Quantity --%>
<asp:TemplateField HeaderText="Quantity">
<ItemTemplate>
   <asp:TextBox ID="txtQuantity" runat="server" CssClass="txtQty"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>

<asp:TemplateField HeaderText="Total">
<ItemTemplate>
    <asp:Label ID="lblTotal" runat="server"></asp:Label>
</ItemTemplate>
</asp:TemplateField>

的GridView

enter image description here

C#代码

for (int i = 0; i < GridView1.Rows.Count; i++)
{
    GridView1.Rows[i].Cells[3].Text = Convert.ToString(Convert.ToDecimal(GridView1.Rows[i].Cells[1].Text) * Convert.ToDecimal(GridView1.Rows[i].Cells[2].Text));
}

5 个答案:

答案 0 :(得分:1)

这是一个混合客户端&amp;服务器端方法,最小化回发(即没有Ajax)

我假设你绑定了一个类似于的实体:(注意Total的初始值是派生的,服务器端)

public class Entity
{
    public int ServiceId { get; set; }
    public decimal Rate { get; set; }
    public int Quantity { get; set; }
    public decimal Total
    {
        get { return Rate * Quantity; }
    }
}

.aspx上,您需要呈现QuantityTotal的初始状态(例如,编辑现有行可能需要相同的页面)。请注意,Total标签是服务器绑定的,但不需要input控件,因为它的值是派生的。 Total将不会回发到服务器。

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
    <asp:GridView runat="server" ID="GridView1" AutoGenerateColumns="false">
        <Columns>
            <asp:TemplateField HeaderText="ServiceID" ItemStyle-Width="100px">
                <ItemTemplate>
                    <asp:Label ID="lblServiceID" runat="server" Text='<%# Eval("ServiceId")%>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>

            <asp:TemplateField HeaderText="Rate" ItemStyle-Width="70px">
                <ItemTemplate>
                    <asp:Label ID="lblRate" runat="server" Text='<%# Eval("Rate")%>' CssClass="rate"></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>

            <asp:TemplateField HeaderText="Quantity">
                <ItemTemplate>
                    <asp:TextBox ID="txtQuantity" runat="server" CssClass="txtQty" Text='<%# Eval("Quantity")%>'></asp:TextBox>
                </ItemTemplate>
            </asp:TemplateField>

            <asp:TemplateField HeaderText="Total">
                <ItemTemplate>
                    <asp:Label ID="lblTotal" runat="server" CssClass='Total'><%# Eval("Total")%></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

在同一个.aspx页面上,添加以下javascript来进行Total的客户端计算,在任何数量的更改时触发。 (并确保您已经引用了jQuery

<script>
    $(document).ready(function () {
        $('.txtQty').on('change', function (evt) {
            var $row = $(this).parents('tr');
            var rate = Number($row.find('.rate').text());
            var qty = Number($(this).val());
            var total = rate * qty;
            $row.find('.Total').text(total);
        });
    });
</script>

在这种情况下,由于计算是简单的乘法,因此可以证明服务器和客户端上的总计算重复是合理的,因为这样可以节省浪费的IO。但是,如果计算更加复杂(例如税,折扣,利息罚款等),那么我建议将计算完全保留在服务器端,然后通过UpdatePanel将参数Ajaxing到服务器的onChange(或者最好是Json / REST API)服务。

答案 1 :(得分:0)

如果由于其他计算或安全原因而严格要在服务器端执行此操作,则必须遍历所有行,然后从labeltextbox控件中找到gridview foreach(GridviewRow row in GridView1.Rows) { if(row.RowType == DataControlRowType.DataRow) { Label total = ((Label)Row.FindControl("lblTotal")); Label rate = ((Label)Row.FindControl("lblRate")); TextBox quantity = ((TextBox)Row.FindControl("txtQuantity")); if(rate != null && quantity != null) { total.Text = (int.Parse(rate.Text) * int.Parse(quantity.Text)).ToString(); } } } 控件{1}}然后您可以更新该值。

{{1}}

答案 2 :(得分:0)

这非常简单:不要这样做。

提前计算所有数据,然后将GridView绑定到数据。这可能意味着您必须向基础数据源添加列,无论是在后面的代码中还是在数据库中。然后计算添加列的值,最后将GridView绑定到完整的数据源。

GridView控件用于显示和编辑数据,而不是用于计算数据。

答案 3 :(得分:0)

foreach(GridviewRow row in GridView1.Rows)
    {
        if(row.RowType == DataControlRowType.DataRow)
        {
            int quantity= 1;
            TextBox txtQuantity = ((TextBox)Row.FindControl("txtQuantity"));
            int.TryParse(txtQuantity.Text,out quantity);
            Label lblRate = ((Label)Row.FindControl("lblRate"));

            decimal total = decimal.Parse(lblRate.Text) * quantity;
            Label lblTotal = ((Label)Row.FindControl("lblTotal"));

            lblTotal.Text = total.ToString();

        }
    }

答案 4 :(得分:0)

下面是一个乘以网格视图列的示例,在另一列中显示该列,然后将该特定列汇总以获得总值

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script type="text/javascript">
        function isNumberKey(evt) {
            var charCode = (evt.which) ? evt.which : event.keyCode
            if (charCode > 31 && (charCode < 48 || charCode > 57))
                return false;
            return true;
        }
        function validateTextBox() {
            ValidateCheckBox()
            //get target base & child control.
            var TargetBaseControl = document.getElementById('<%=this.gv1.ClientID%>');
            var TargetChildControl1 = "text1";

            //get all the control of the type INPUT in the base control.
            var Inputs = TargetBaseControl.getElementsByTagName("input");

            for (var n = 0; n < Inputs.length; ++n)
                if (Inputs[n].type == 'text' && Inputs[n].id.indexOf(TargetChildControl1, 0) >= 0)
                    if (Inputs[n].value != "") return true;
            alert('Enter some value in textbox!');
            return false;
        }
        function ValidateCheckBox() {            
            //get target base & child control.
            var TargetBaseControl = document.getElementById('<%=this.gv1.ClientID%>');
           var TargetChildControl = "check1";    //get all the control of the type INPUT in the base control.
           var Inputs = TargetBaseControl.getElementsByTagName("input");
           for (var n = 0; n < Inputs.length; ++n)
               if (Inputs[n].type == 'checkbox' && Inputs[n].id.indexOf(TargetChildControl, 0) >= 0)
                   if (Inputs[n].checked) return true;
           alert('Select at least one checkbox!');
           return false;
       }

    </script>
    <style type="text/css">
        .auto-style1 {
            text-decoration: underline;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <div>
       <center>
        <asp:GridView ID="gv1" AutoGenerateColumns="False" 
            runat="server" Height="115px" Width="373px" OnSelectedIndexChanged="gv1_SelectedIndexChanged" DataSourceID="SqlDataSource1" >
         <Columns>             
             <asp:TemplateField>
                 <ItemTemplate>
                     <asp:CheckBox ID="check1" runat="server" AutoPostBack="true"  />
                 </ItemTemplate>
             </asp:TemplateField>             
             <asp:BoundField HeaderText="ProductId" DataField="ProductId" InsertVisible="False" ReadOnly="True" SortExpression="ProductId" />
             <asp:BoundField HeaderText="ProductName" DataField="ProductName" SortExpression="ProductName" />
             <asp:BoundField HeaderText="Price" DataField="Price" SortExpression="Price" />
             <asp:TemplateField HeaderText="Enter Quantity">
                 <ItemTemplate>
                     <asp:TextBox ID="text1" runat="server" MaxLength="10" Onkeypress="return isNumberKey(event)"/>    
                 </ItemTemplate>
             </asp:TemplateField>
             <asp:TemplateField HeaderText="Total">
                 <ItemTemplate>
                    <asp:Label ID="lbltotal1" runat="server" Text="Label"></asp:Label>  
                 </ItemTemplate>
             </asp:TemplateField>              
         </Columns>
        </asp:GridView>
            <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:BaviConnectionString %>" SelectCommand="SELECT [ProductId], [ProductName], [Price] FROM [Product]"></asp:SqlDataSource>
            <asp:Button ID="Button1" runat="server" Text="View" OnClientClick="javascript:return validateTextBox();" OnClick="Button1_Click" />
            </center>
                <br />
                <br />

    <center>
    <h><strong><span class="auto-style1">Selected Product</span><br />
    </strong></h>
        &nbsp;<asp:GridView ID="gv2" AutoGenerateColumns="False" runat="server" >
        <Columns>  
         <asp:BoundField HeaderText="ProductName" DataField="ProductName" SortExpression="ProductName" />      
         <asp:BoundField HeaderText="Price" DataField="Price" SortExpression="Price" />
         <asp:BoundField HeaderText="Quantity" DataField="Quantity" SortExpression="Quantity" />
         <asp:BoundField HeaderText="Total" DataField="Total" SortExpression="Total" />       
        </Columns>
        </asp:GridView>
    <br />
    <asp:Label ID="Label1" runat="server" Text="Total Price" ></asp:Label>         
    <asp:TextBox ID="txttotal" runat="server" Width="75px"></asp:TextBox>
    </center>

            </div>

        </div>
    </form>
</body>
</html>

 protected void Button1_Click(object sender, EventArgs e)
{
    DataTable dt = new DataTable();
    dt.Columns.AddRange(new DataColumn[4] {
        new DataColumn("ProductName"),
        new DataColumn("Price"),
        new DataColumn("Quantity"),
        new DataColumn("total")
    });

    foreach (GridViewRow row in gv1.Rows)
    {
        if (row.RowType == DataControlRowType.DataRow)
        {

            CheckBox chk = (row.Cells[0].FindControl("check1") as CheckBox);
            string qty = ((TextBox)gv1.Rows[row.RowIndex].FindControl("text1")).Text;[enter image description here][1]

            if (chk.Checked)
            {
                string name = row.Cells[2].Text;
                string Price = row.Cells[3].Text;
                string Quantity = qty;                  
                ((Label)gv1.Rows[row.RowIndex].FindControl("lbltotal1")).Text = Convert.ToString(Convert.ToInt32(qty) * Convert.ToInt32(Price));
                string Ttl = ((Label)gv1.Rows[row.RowIndex].FindControl("lbltotal1")).Text;
                tprice += int.Parse(Ttl);
                dt.Rows.Add(name, Price, Quantity, Ttl);
            }

        }

    }
    txttotal.Text = tprice.ToString();
    gv2.DataSource = dt;
    gv2.DataBind();

}

[这将是最终输出][1]