Add calculated column to a GridView - c#

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>

Related

Grab the first to fourth characters from string and change it to other character in Gridview

I currently have a Gridview with certain numbers of columns. In one of the columns, I have users' contact number, thus I want to mask the first four number. Is there a way to do it?
For example:
123456
I want to only have the last two numbers visible. Thus, the output would be
XXXX56
Is there a way?
<asp:GridView ID="gvAttendance" runat="server" AutoGenerateColumns="false" CssClass="table table-bordered table-hover table-striped gvv">
<Columns>
<asp:BoundField DataField="userCN" HeaderText="Contact Number" />
</Columns>
</asp:GridView>
The easiest way I can think of is creating a function that returns the anonymized string inside the GridView ItemTemplate.
<asp:TemplateField>
<ItemTemplate>
<%# anonymizeString(Eval("userCN").ToString()) %>
</ItemTemplate>
</asp:TemplateField>
And the function
public string anonymizeString(string input)
{
if (!string.IsNullOrEmpty(input) && input.Length > 5)
{
return "XXXX" + input.Substring(4, 2);
}
else
{
return input;
}
}
Or as one-liner in the GridView
<%# (!string.IsNullOrEmpty(Eval("userCN").ToString()) && Eval("userCN").ToString().Length > 5) ? "XXXX" + Eval("userCN").ToString().Substring(4, 2) : Eval("userCN").ToString() %>

Set double as a Label in a GridView

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;

How to trim the column in gridview

i have a gridview, the column has 20 records whose values are in decimal.say like 5686252.345656 i want to trim those value. So that i could see 5686252.34. It would be great if i trim it in the c# code rather in SQL.
Ive binded the values like this..
<asp:TemplateField HeaderText="Weighted Avg" SortExpression="WT_AVG"
ItemStyle-HorizontalAlign="Center" HeaderStyle-VerticalAlign="Top" HeaderStyle-Width="70px">
<ItemTemplate>
<asp:Label ID="lblWT" runat="server" Text='<%# DataBinder.Eval(Container.DataItem,"WT_AVG") %>' />
</ItemTemplate>
</asp:TemplateField>
Please help me.
Thanks.
You can apply a format string to the binding statement:
Example:
<%# DataBinder.Eval(Container.DataItem, "Price", "{0:c}") %>
I would use Math.Round(decimal d,int decimals) for example
Math.Round(3.44, 1); //Returns 3.4.
Math.Round(3.45, 1); //Returns 3.4.
Math.Round(3.46, 1); //Returns 3.5.
Math.Round(4.34, 1); // Returns 4.3
Math.Round(4.35, 1); // Returns 4.4
Math.Round(4.36, 1); // Returns 4.4
http://msdn.microsoft.com/en-us/library/zy06z30k(v=vs.100).aspx
EDIT: OR do it in the SQL:
SELECT ROUND(123.9994,3), ROUND(123.9995,3)
returns: 123.9990 124.0000
Rounding on MSDN

How do I set the GridView RowHeaderColumn to a TemplateField?

I have a standard ASP.NET GridView and I'd like the first column (a emplateField) to be rendered as <th>, or in ASP.NET terms, I'd like to set it to the GridView RowHeaderColumn property. But that property is looking for the name of a DataItem (from a BoundColumn).
How can I render my TemplateField with <th> tags?
Finally found a workaround for this. I am not sure if this code has anything to do with good ASP.NET practices, but it does the trick:
public class FirstColumnHeaderGridView : GridView
{
protected override void InitializeRow(GridViewRow row, DataControlField[] fields)
{
DataControlFieldCell cell = new DataControlFieldHeaderCell(fields[0]);
DataControlCellType header = DataControlCellType.DataCell;
fields[0].InitializeCell(cell, header, row.RowState, row.RowIndex);
row.Cells.Add(cell);
DataControlField[] newFields = new DataControlField[fields.Length - 1];
for (int i = 1; i < fields.Length; i++)
{
newFields[i - 1] = fields[i];
}
base.InitializeRow(row, newFields);
}
}
Let me explain what is going on here. We are creating a special type of GridView, that will render its first column using <th> tags no matter how this column is created. For this we are overriding the InitializeRow method. This method basically configures cells for the row. We are handling the first cell, and let standard GridView take care of the rest.
The configuration we are applying to the cell is fully taken from the GridView implementation and is enough for the cell to be rendered with <th> tag instead of <td>.
After that workaround the usage is absolutely standard - register our class as a server control and use it as usual GridView:
<%# Register Assembly="WebApplication1" Namespace="WebApplication1" TagPrefix="wa1" %>
...
<wa1:FirstColumnHeaderGridView ID="Grid1" runat="server" ...>
<Columns>
<asp:TemplateField>
<ItemTemplate>
Will be inside th
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
Will be inside td
</ItemTemplate>
</asp:TemplateField>
</Columns>
</wa1:FirstColumnHeaderGridView>
Is this what you mean?
<Columns>
<asp:TemplateField HeaderText="Código" ItemStyle-Width="9%">
<HeaderTemplate>
<asp:Label runat="server" Text="CodigoSAP"></asp:Label>
</HeaderTemplate>
<ItemTemplate>
<asp:Label runat="server" ID="lblCodigoSAP" Text='<%# Bind("CodigoSAP") %>'> </asp:Label>
</ItemTemplate>
</asp:TemplateField>
I'm almost sure I'm getting the wrong idea, what do you say?
Late to the game, but we needed to set scope="row" in a middle column, not the first. To make it generic, in a derived GridView class I added the following property (similar to the GridView's built-in RowHeaderColumn property):
public int? RowHeaderColumnIndex
{
get { return (int?)ViewState["RowHeaderColumnIndex"]; }
set { ViewState["RowHeaderColumnIndex"] = value; }
}
Then set the scope:
protected override void OnRowCreated(GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && RowHeaderColumnIndex.HasValue)
{
e.Row.Cells[RowHeaderColumnIndex.Value].Attributes["scope"] = "row";
}
}
When you place your custom grid just set RowHeaderColumnIndex="0" for the first column, "1" for the 2nd column and so on.

To add a Serial Number as the First Column in a GridView

I have a Grid View . It has two bound columns. I need to have a Serial Number column as the first column.
How can i do that ?
Thanks in Advance
<asp:TemplateField HeaderText="S No">
<ItemTemplate>
<%# Container.DataItemIndex + 1 %>
</ItemTemplate>
<ItemStyle Width="2%" />
</asp:TemplateField>
Create a datatable with two columns use a first column as autoincrement as true and AutoIncrementStep=1 like
DataTable _test = new DataTable();
DataColumn c = new DataColumn("sno", typeof(int));
c.AutoIncrement = true;
c.AutoIncrementSeed = 1;
c.AutoIncrementStep = 1;
_test.Columns.Add(c);
_test.Columns.Add("description");
gvlisting.DataSource = _test;
This is more of an adjunct answer to the OP's original question. I had a terrible time figuring out how to get the index number (serial number in the OP) of the row created by the R.Ilayaraja's answer (which worked great BTW).
In your code behind page if you want to get the index number of the row, you can use code similar to this:
Int32 idNumber = Convert.ToInt32(gvlisting.Rows[i].DataItemIndex.ToString()) + 1;
This assumes you were using an iterator 'i' to get other values from your rows, and you need to add one to the number since the index is ordinal (index 0 is the first row). If you're not using an iterator, just use .Rows[0]
I struggled mightily as an ASP.NET nugget to figure this out, so I figured I'd post this in hopes it helps some other noob like me.
Add a column called Ser and set it to ReadOnly=false.
Then add this code to your application:
if (GridSearch.Rows.Count > 1)
{
for (int i = 0; i < GridSearch.Rows.Count-1; i++)
{
GridSearch.Rows[i].Cells[0].Value = (i + 1).ToString();
}
}
Just add this code in gridview
<asp:TemplateField HeaderText="Serial No of Users">
<ItemTemplate>
<%# ((GridViewRow)Container).RowIndex + 1%>
</ItemTemplate>
<FooterTemplate>
<asp:Label ID="lbltotalall" runat="server" />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="SR No">
<ItemTemplate>
<%# Container.DataItemIndex + 1 %>
</ItemTemplate>
<ItemStyle Width="5%" />
</asp:TemplateField>
use Row index a bound field or on row data bound you can add a template column on which you could use the index of the row.

Categories

Resources