Set double as a Label in a GridView - c#

I am creating a shopping cart. I have a GridView with all of my products and I have an update button which, when clicked, I want to take the values in the price column and multiply it with the input values in the quantity TextBox and display it in the ItemTotal Label. My SQL inputs for lblPrice is in decimal form and however it is displayed on the gridview as $_.00. I keep running into a Format Exception for lblPrice. I was wondering if there is a way for me to convert lblPrice back to a decimal but still have it displayed as a price on the gridview?
ShoppingCart.aspx
<asp:TemplateField HeaderText="Price">
<ItemTemplate>
<asp:Label ID="lblPrice" runat="server" Text='<%# Bind("Price")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Quantity">
<ItemTemplate>
<asp:TextBox ID="txtQuantity" runat="server"></asp:TextBox>
<asp:CompareValidator runat="server" Operator="DataTypeCheck" Type="Integer"
ControlToValidate="txtQuantity" ErrorMessage="Value must be a whole number" ForeColor="Red" />
</ItemTemplate>
</asp:TemplateField>
ShoppingCart.aspx.cs
protected void btnUpdate_Click(object sender, EventArgs e)
{
foreach (GridViewRow row in gvProductsList.Rows)
{
double lblPrice = Convert.ToDouble(((Label)row.FindControl("lblPrice") as Label).Text);//convert value of lbl to double
int txtQuantity = int.Parse(((TextBox)row.FindControl("txtQuantity") as TextBox).Text);//convert value of textbox to int
Label lblItemTotal = (row.FindControl("lblItemTotal")) as Label;//find lblItemTotal label in each row
lblItemTotal.Text = Convert.ToString(lblPrice * txtQuantity);
}
}

After some discussion in the comments, we discovered that the problem was this line:
double lblPrice = Convert.ToDouble(((Label)row.FindControl("lblPrice") as Label).Text);
The value of the label was something like $3.00. The conversion to a double was failing. This is because the string contains a dollar sign, which isn't a valid number.
What you can do is convert this back into a decimal via the Parse method, passing in the appropriate NumberStyle - in this case, Currency.
Label lblPrice = (Label)row.FindControl("lblPrice");
decimal price = decimal.Parse(lblPrice.Text, NumberStyles.Currency);
You may want to look into TryParse instead, for better error handling.
Make sure to include the Globalization namespace in order to use NumberStyles.
using System.Globalization;

Related

How To select Particular Cell Value in Grid View

I want to select Particular Cell value and will use to Bind Controls But i am Not able to select Cell Value
Its not retrieving data
ASPX Code
<asp:GridView ID="grdLogedUserDetails" OnRowDeleting="grdLogedUserDetails_RowDeleting" OnRowDataBound="grdLogedUserDetails_RowDataBound"
runat="server" Style="width: 100%; text-align: center" OnRowCommand="grdLogedUserDetails_RowCommand"
class="table table-striped table-bordered" AutoGenerateColumns="false" datakeynames="Ref_ID">
<Columns>
<asp:TemplateField HeaderText="Process No">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Bind("Ref_ID") %>' ID="lblRef_ID"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Company">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Bind("CompanyName") %>' ID="lblCompanyName"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Division">
<ItemTemplate>
<asp:Label runat="server" Text='<%# Bind("DivisionName") %>' ID="lblDivisionName"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:ImageButton ID="imgDel" runat="server" ImageUrl="~/Images/delete.png" AlternateText="Delete" CommandName="Delete" />
</ItemTemplate>
<ItemStyle Width="100px" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<asp:ImageButton ID="imgSel" runat="server" ImageUrl="~/Images/edit-icon.png" AlternateText="Select" CommandName="Select" />
</ItemTemplate>
<ItemStyle Width="100px" />
</asp:TemplateField>
C#
protected void grdLogedUserDetails_RowCommand(object sender, GridViewCommandEventArgs e)
{
int rowIndex = Convert.ToInt32(e.CommandArgument);
//Reference the GridView Row.
GridViewRow row = grdLogedUserDetails.Rows[rowIndex];
//Access Cell values.
int RefID= int.Parse(row.Cells[0].Text);
string Company= row.Cells[1].Text;
string Division= row.Cells[2].Text;
}
protected void grdLogedUserDetails_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Access Cell values.
var RefId = int.Parse(e.Row.Cells[0].Text); // Error Input string is not in correct Formate
string Comany= e.Row.Cells[1].Text;
string Division= e.Row.Cells[2].Text;
}
}
While Debugging I can see Error Like :
"Input string is not in correct Format" Where i am doing wrong
My Table Structure
________________________________________
Ref_ID| CompanyName | DivisionName |
______|_______________|_________________|
6 | Company | Sales |
8 | Company | Sales |
14 | Company | Sales |
______|_______________|_________________|
RefID i have taken as "int" and CompanyName and DivisionName "string" so where i my input string is in wrong format,
Where i am doing wrong Please suggest me on same
The rowcommand event does not trigger rowindexed change unless you have Command="Select" but you DO HAVE Command="Select". However, you don't have a CommandArugment.
However, since you do have command=Select, then move your code to SelectedIndexChanged. The issue is you can't get/grab the row from the "row" command event since the row has not changed. The rowcommand event fires before SelectedIndexChanged. And as noted, unless you use a special command (delete or select) then SelectedIndexChanged does NOT fire.
So rowindex will NOT have been set in the row command event. However, this will mean that for your select button (and delete) your code will be (can be) in rowindexchanged "if" you use say select (or "delete") for the command. if you use a custom command name, then rowindexedchanged does NOT fire.
You can continue to use rowcommand, but you need the CommandArugment to pass either the PK of the row, or the index of the row.
So you have two choices here. (actually 3).
You can set the value of CommandArugment of that button.
Either to the PK, or you can use this
CommandArgument ='<%# Container.DataItemIndex%>'
I note that in your command settings, you are NOT setting the CommandArugment - you have to set it in your markup. The above expression will return the index into the grid.
You can move your code to rowindexchanged.
However, there is a 3rd choice. You CAN GET the rowindex in rowcommand. So from the depths of hell, you can use this stunning whopper insane of a statement:
If e.CommandName = "MySelect" Then
' now get row.
Dim gvRow As GridViewRow = CType(CType(e.CommandSource, Control).NamingContainer, GridViewRow)
Debug.Print("row index = " & gvRow.DataItemIndex)
Dim MyLabel As Label = gvRow.FindControl("HotelName")
Debug.Print("Value ref id = " & MyLabel.Text)
End If
Note VERY careful:
For the templated fields - we use find control. For non tempalted fields, then you can reference by cell.
Now that super award winning ugly way to get the row in row command?
In C# it will look like this:
{
GridViewRow gvRow = (GridViewRow)(Control)e.CommandSource.NamingContainer;
}
So, you have to use above, or as noted, move your code to SelectedIndexChanged.
Since you only have a select and delete button, then I would suggest SelectedIndexChanged. But if you were to say introduce another button - then you would not want to use Select or Delete, but a custom command name of your choosing (say CommandName="MyViewer"). In that case, then SelectedIndexChanged will not fire. But then you would have a means to determine which button was clicked upon (beyond the need of select and delete commands).
So in summary:
You have about 3+ ways to do this.
Keep in mind that in row command, the selected index event has NOT yet fired.
Keep in mind that if you use a custom row command name, then selected index WILL NOT fire.
Keep in mind that you can pick up the selected row with that award winning ugly line of code.
Keep in mind that you can't use cells() collection for your custom templated columns - so use find control.
Keep in mind that selectedindex in row command event has NOT changed nor fired yet.
Since you ARE using select, then you have a choice of row command event, or selectedindex changed event - they will both fire in your case.
The problem is that the cell does not contain any text, but a Label lblRef_ID. So you need to access the label, not the cell value.
var label = e.Row.FindControl("lblRef_ID") as Label;
var RefId = int.Parse(label.Text);

Add calculated column to a GridView

I have a GridView with two columns and I want to add a third column which will be column A divided by column B. I added a template field but I am getting a divide by zero error. How can I check for zero values to stop the error message?
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblCalc" runat="server" >
<%# Convert.ToDecimal(Eval("val1").ToString()) / Convert.ToDecimal(Eval("val2").ToString()) %>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
Yes, you sure can. You can even do that inline, but that would clutter your markup too much, so I would suggest moving this code to code behind.
protected decimal Calculate(string a, string b)
{
decimal ad = Convert.ToDecimal(a);
decimal bd = Convert.ToDecimal(bd);
if (bd == 0)
{
return 0; // or whatever
}
return ad / bd;
}
To call this:
<asp:Label ID="lblCalc" runat="server" >
<%# Calculate(Eval("val1").ToString(), Eval("val2").ToString()) %>
</Label>

Hidden Field Value not finding value

I have an hiddenfield field in my gridview but the code behind cant get its value maybe someone could find the problem.
HTML:
<asp:TemplateField HeaderText="TweetID" Visible="false">
<ItemTemplate>
<asp:HiddenField ID="TweetID" runat="server" Value='<%#Eval("TweetID") %>' />
</ItemTemplate>
</asp:TemplateField>
.cs:
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
int index = Convert.ToInt32(e.RowIndex);
HiddenField tid = GridView1.Rows[index].FindControl("TweetID") as HiddenField;
//Response.Write(tid.Value);
TweetHelper.RemoveTweet( Convert.ToInt32(tid.Value), 1);
}
by the way the response writes nothing.
Based on your code above what you are doing is overkill.
Either make TweetID a Gridview.DataKey.
Or if that's not an option, convert your Delete button to a template field and add TweetID as a CommandArgument to the Delete button.
Your code should work fine.However another way to find the control is
GridViewRow row = GridView1.Rows[e.RowIndex];
HiddenField hdn = (HiddenField)row.FindControl("TweetID");
string value = hdn.Value;
or simply
var tweetid = ((HiddenField)GridView1.Rows[e.RowIndex].FindControl("TweetID")).Value;

cell value in gridview is not getting in asp.net

im not getting the valu of specic row in row data bound event , value coming null;
<asp:TemplateField>
<HeaderTemplate>
Today's pos
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lbl_TodayPos" runat="server" Text='<%# Eval("CurrentPosition") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
aspx.cs code
protected void GrdKeyWord_RowCommand(object sender, GridViewCommandEventArgs e)
{
string value = GrdKeyWord.Rows[rowindex].Cells[5].ToString();
}
The value you are looking for is stored in a label control not in a table cell. Therefore, you need to use FindControl on that row to access the lbl_TodayPos:
Label myLabel = (Label)GrdKeyWord.Rows[rowindex].FindControl("lbl_TodayPos");
string value = myLabel.Text;
If you autogenerate the columns in the gridview, or if you used 'BoundField' (instead of TemplateField) you could use .Cells[]. Because, in this case, you would have gridview rendered as pure html table with table cells.

Can I apply unit conversion to a gridview column?

I have a column in my gridview which displays the total cost of certain items which is pulled from my database table. However, my users also have a currency information attached to their account. What I would like to do is convert this column based on the individual user's currency info. I have tried the following:
<asp:HiddenField id="currencyconvfactor" runat="server" />
<asp:TemplateField HeaderText="Total" SortExpression="Total">
<ItemTemplate>
<%# currencyconvfactor.Value %> //this is just a test. see below for the issue.
</ItemTemplate>
</asp:TemplateField>
Code Behind
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
currencyconvfactor.Value = 12345
//i simplified retrieving the specific factor value here as I do some database commands to pull the specific value
}
However, I notice that the template field column is always empty. Does that mean that the gridviews are generated before the page load event? If so, how could I perform the column conversions on the first page load? More specifically, how can I access the conversion factor to perform the conversion in time?
You may want to look at using a RowDataBound event to access the column and do whatever computation you need:
.aspx:
<Columns>
<asp:TemplateField HeaderText="Template Field">
<ItemTemplate>
<asp:Label ID="lblConvValue" Runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
Code-behind:
void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Get the current row's data
DataRowView rowView = (DataRowView)e.Row.DataItem;
// Do your conversion
var conv = int.Parse(rowView["valueToConvert"].ToString());
var converted = conv * 12345; // Whatever conversion you want.
// Set the value of the control in the ItemTemplate
Label lblConvValue= (Label)e.Row.FindControl("lblConvValue");
lblConvValue.Text = converted.ToString();
}
}
If all rows use the same Currency conversion factor, you can do the following.
...
<ItemTemplate>
<%#GetCurrencyconvfactor()%>
</ItemTemplate>
...
In the code behind define a method to return the value
public string GetCurrencyconvfactor()
{
//you can also pass in custID as an argument if each row uses different factor
return "123"; // or get this from the user profile/settings
}
After defining the values​​, call GridView.DataBind()

Categories

Resources