?
Solved

Calculated field in a gridview

Posted on 2011-09-07
15
Medium Priority
?
2,917 Views
Last Modified: 2012-06-21
Hi experts

Using asp.net 4 with either C# or vb.net as the code behind I want to have a calculated field in a gridview, i have researched how to do this and it seems there are several options, in my gridview amongst other fields i have:  Item_Price, Quantity and Total, i want the Total field to = the Item_Price * Quantity, the only bound field is the Item_Price the other two are Templates, i have tried using:

<asp:TemplateField HeaderText="Total">
<ItemTemplate>
<asp:Label Text='<% Eval ("Item_Price") * Eval ("Quantity") %>'
runat="server"/>
</ItemTemplate>
</asp:TemplateField>



This does not work though, ideally I would like a checkbox in the gridview to trigger the calculation.
Hope somebody can help
0
Comment
Question by:dizzycat
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
  • 4
  • +1
15 Comments
 
LVL 5

Expert Comment

by:gingermoleman
ID: 36495603
Hi,

A couple of different approaches you could take. You could do the sum in your SQL query and return it as its own field

ie

SELECT  ([item_price] * [Quantity]) as total
but this would require holding the quantity in the DB

If quantity is a user entered value then you can do it this way

in the grid view:

           <asp:TemplateField HeaderText="Total" SortExpression="Total">
            <ItemTemplate>
        <asp:Label ID="TotalLabel" runat="server" Text='<%#calcTotal (# Bind("DBID"),# Bind("DBID"))%>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>

this calls a function called calcTotal and passes it the two values, in your code behind you need to add the function:

Function calcTotal(ByVal value1 As Decimal, ByVal value2 As Decimal)
        Return value1 * value2
    End Function

Let me know if you need more help.

GMM
0
 
LVL 7

Accepted Solution

by:
JosephEricDavis earned 2000 total points
ID: 36495705
There is another cleaner way to do this utilizing your code behind.

Step 1: Give your label and ID and leave it's text property blank...
<asp:Label runat="server" ID="lblTotalCost"></asp:Label>

Step 2: In the declaration of the gridview you will want to define the attribute OnRowDataBound.
<asp:GridView runat="server" ID="gvYourGridView" OnRowDataBound="gvYourGridView_OnRowDataBound">

Now, you need to make sure that you add all of your other necessary gridview attributes that fit your needs.  What I have above is just an example of how to add the OnRowDataBound event handler to the gridview.

Step 3: In your code behind add the event handler.
protected void gvYourGridView_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                       //Find the data row bound to the grid view row
                       DataRowView drv = (DataRowView)e.Row.DataItem;

                       //Find the label in question
                       Label lbl = e.Row.FindControl("lblTotalCost") as Label;

                       //Perform your needed calculation
                       lbl.Text = (Convert.ToDouble(drv["Item_Price"].ToString()) * Convert.ToDouble(drv["Quantity"].ToString())).ToString();
            }
}

Let me know if you have any questions on this solution.  I would be happy to clear anything up.
0
 

Author Comment

by:dizzycat
ID: 36495886
I am using code below:

<asp:TemplateField HeaderText="Total">
                <ItemTemplate>
                <asp:Label ID="Label1" runat="server" Text='<%#calcTotal(#Bind("Quantity"),#Bind("Price"))%>'></asp:Label>
                </ItemTemplate>

But getting error message:

Preprocessor directives must appear as the first non whitespace character on a line.

Any ideas
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 7

Expert Comment

by:JosephEricDavis
ID: 36495894
Can you copy and past the first few lines of your aspx file here?
0
 

Author Comment

by:dizzycat
ID: 36495929
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default4.aspx.cs" Inherits="Default4" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
0
 
LVL 7

Expert Comment

by:JosephEricDavis
ID: 36495992
Yeah, I'm not sure.

But again, I would call your attention to my earlier post as another course of action.  Whenever you use code like this

<%# blah blah blah %>

You are including in your aspx page code that is intended to go into your code behind.  This is usually fine, but at the end of the day it is not a best practice as it is not separating your presentation layer from your business logic.

Before you try this you might try removing the server side include in the label to see if the error continues to happen, just to verify what is actually causing your error.

<asp:Label ID="TotalLabel" runat="server" Text='testing'>
0
 
LVL 5

Expert Comment

by:gingermoleman
ID: 36496002
Did you convert the function to c# (mine was VB)

public object calcTotal(decimal value1, decimal value2)
{
      return value1 * value2;
}

though I have to say that Josephs suggestion is probably the better one to learn as there is lots more you can do in the rowDataBound event (where as mine just multiplies)

GMM
0
 
LVL 5

Expert Comment

by:gingermoleman
ID: 36496088
Hi,

Try this
<asp:Label ID="Label1" runat="server" Text='<%#calcTotal(Bind("Quantity"),Bind("Price"))%>'></asp:Label>

instead of this
<asp:Label ID="Label1" runat="server" Text='<%#calcTotal(#Bind("Quantity"),#Bind("Price"))%>'></asp:Label>


my fault, I wrote the original bit out without actually testing it, you dont want the extra #'s



GMM
0
 

Author Comment

by:dizzycat
ID: 36496249
I've done what you said GMM

But now getting 2 errors both saying:

The name Bind does not exist in the current context

0
 

Author Comment

by:dizzycat
ID: 36496306
This is my C# code behind:

public object calcTotal(decimal Quantity, decimal Price)
    {
        return Quantity * Price;
    }
0
 

Author Comment

by:dizzycat
ID: 36496425
A quick question to Joseph:

You used the OnRowDataBound event, I can only find the RowDataBound event, are they the same?
0
 
LVL 7

Expert Comment

by:JosephEricDavis
ID: 36496461
OnRowDataBound should be one of the available options provided by intellisense when you are inside the <asp:GridView> tag.  I just double checked on a working example that I have locally and it definitely has the 'On' as part of the property name.

If you don't have it as part of your intellisense list, I would try to go ahead and just type it in like I have it and see what happens.
0
 
LVL 5

Expert Comment

by:gingermoleman
ID: 36496521
Hi,

its definately has the 'on' bit and Josephs solutions does the job perfectly. Bit baffled by the errors your getting from mine, I can recreate them all! works a treat when coded in VB though.

GMM
0
 

Author Closing Comment

by:dizzycat
ID: 36497154
Got it working.

I think I will stick to using the code behind file as much as possible in the future, as you say keep the two layers separate. I'm sure I will be back asking more questions about manipulating a gridviews data very soon, but until then thanks for your help.
0
 
LVL 4

Expert Comment

by:guramrit
ID: 36497155
The code you'd written in question is correct, it should work. It's working in my project too.

<asp:TemplateField HeaderText="Total">
 <ItemTemplate>
  <asp:Label Text='<% Eval ("Item_Price") * Eval ("Quantity") %>' runat="server"/>
 </ItemTemplate>
</asp:TemplateField>

Open in new window


But the problem is with next requirement (CheckBox column), I'm writting following code which should work with CheckBox, which should work.

<asp:GridView runat="server" ID="GC" AutoGenerateColumns=false>
            <Columns>
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:CheckBox runat="server" ID="CB" AutoPostBack="true" />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="Item_Price" HeaderText="Item Price" />
                <asp:TemplateField HeaderText="Quantity">
                    <ItemTemplate>
                        <asp:Label runat="server" Text='<%# Eval("Quantity") %>' />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Total">
                    <ItemTemplate>
                        <asp:Label runat="server" Text='<%# if(CType(CType(Container, GridViewRow).FindControl("CB"), CheckBox).Checked,  Eval("Quantity") * Eval("Item_Price"),0) %>' />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>

Open in new window


 Now The problem comes, In gridview if we add a checkbox in template column with AutoPostBack="true". Now if we mark it checked in runtime then after postback it'll uncheck automatically, If somehow you make its state persisted, then your work'll be done.
Problem is with checkbox, not with CalculatedColumn
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Just a quick little trick I learned recently.  Now that I'm using jQuery with abandon in my asp.net applications, I have grown tired of the following syntax:      (CODE) I suppose it just offends my sense of decency to put inline VBScript on a…
IntroductionWhile developing web applications, a single page might contain many regions and each region might contain many number of controls with the capability to perform  postback. Many times you might need to perform some action on an ASP.NET po…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question