Hi i have a dataset which contains a table retrieved from sql. It has 'product' column and 'price' column. I got the dataset and binded to grid. Now i want to make the grid's price column to be formatted to 2 decimal places(validation). Any idea please.
I should not change the select query since its an SP which gives me the dataset.
if you neither want to use Bound-Field nor change select query than as much i know you have two options left to accomplish this. First is, do value change in your dataset before binding to grid using any loop and the second option is alter values in grid on RowDataBound Event...
By altering value in Dataset:
foreach(dataRow[] dr in dataset.tables[your table index])
{
// max. two decimal places
string val = String.Format("{0:0.##}",Convert.ToDecimal(dr[column index]));
dr[column index] = val;
}
By altering value in Grid:
protected void mygrid_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
mygrid.cell[cell index].Text = String.Format("{0:0.##}",Convert.ToDecimal(dataset.tables[table index][column index][Row Index]));
}
}
Now if you want apply validation for data insert and update you can apply RegularExpressionValidator at your textBox ...
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ErrorMessage="RegularExpressionValidator"
ControlToValidate="TextBox1" ValidationExpression="^\d{1,2}([.]\d{1})$"> ValidationGroup="MyVal"</asp:RegularExpressionValidator>
Now you have to apply
ValidationGroup="MyVal"
also on click control on which you'll perform its editing and update..
Try this:
<asp:BoundField DataField="Price" DataFormatString="{0:C2}" HeaderText="Price" />
You need to add the "DataFormatString" property to the bound field as shown above. This formats currency values to two decimal places. Check this article.
DataField refers to the name of the column in the datatable, whereas the HeaderText refers to the text which would be shown as the header of the column in grid.
Related
I have a simple code that displays the results with a simple thank you
I just want to fetch the row number that contains a specific value, knowing that the value is unique
For example, the owner id is 3, who got 939119, falls in row number 7
enter image description here
GridView1.DataSource = dt;
dt.DefaultView.Sort = "CRPoints DESC";
GridView1.DataSource = dt.DefaultView;
GridView1.DataBind();
string idcc = GridView1.DataKeys[e.RowIndex].Values[3].ToString();
Label1.Text = idcc;
idcc = 7
Ok, I'm going to be nice today. but, I WILL state that your posted code makes ZERO sense without any context.
I would assume a typical setup is you have a GV. You load it up with data.
Then say on a row click, you want to get information about that row.
So, lets do this with a simple grid.
our GV markup is thus this:
<asp:GridView ID="GVHotels" runat="server" CssClass="table table-hover"
DataKeyNames="ID" AutoGenerateColumns="false" Width="40%" >
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="First Name" HeaderStyle-Width="100" />
<asp:BoundField DataField="LastName" HeaderText="Last Name" HeaderStyle-Width="100" />
<asp:BoundField DataField="HotelName" HeaderText="Hotel Name" HeaderStyle-Width="120"/>
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="Description" HeaderText="Province" />
<asp:TemplateField HeaderText="hotel as text box">
<ItemTemplate>
<asp:TextBox ID="txtHotel" runat="server" Text="<%# Eval("HotelName") %>" >
</asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="cmdView" runat="server" Text="Row Click" CssClass="btn"
OnClick="cmdView_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
So, two things you have to "learn" or remember:
to get a databound field from the GV, you use .Cells[] collection (starting at 0 for the first column.
to get a "control" you dropped into the GV, you have to use FindControl.
And to drop/have/use/enjoy a plain jane button or drop down, or ANY standard asp.net control in the GV, you have to "wrap" it as the above markup shows (inside of a "TemplateField", and then inside of "ItemTemplate".
So, often you just use "BoundField", but often you can (and will want to) use a standard control in the grid row.
A great example in above is the placing of a plane jane button click in the row (as per above rules).
So, we have this code to load the GV:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid();
}
void LoadGrid()
{
string strSQL = "SELECT * FROM tblhotelsA ORDER BY HotelName";
GVHotels.DataSource = MyRst(strSQL);
GVHotels.DataBind();
}
And now we have/see this:
So, now our button click (to get the one row we click on).
this:
protected void cmdView_Click(object sender, EventArgs e)
{
Button cmdMyRowBtn = (Button)sender;
GridViewRow MyRow = (GridViewRow)cmdMyRowBtn.NamingContainer;
int PKID = (int)GVHotels.DataKeys[MyRow.RowIndex]["ID"];
Debug.Print($"Row index click = {MyRow.RowIndex.ToString()}");
Debug.Print($"Data base PK id = {PKID.ToString()}");
// get a "databound" field - use cells colleciton
Debug.Print($"Hotel name from cells field = {MyRow.Cells[2].Text}");
// get a tempatled column (those standard asp.net controls in the gv
TextBox txtHotel = (TextBox)MyRow.FindControl("txtHotel");
Debug.Print($"Hotel name from text box in gv = {txtHotel.Text}");
}
So, above, when you click, you can then do whatever you want. You can get values, take values and fill out some text boxes - do whatever.
The output from above click is this:
output:
Row index click = 1
Data base PK id = 5
Hotel name from cells field = Inns of Banff
Hotel name from text box in gv = Inns of Banff
So, from above, you should be able to do quite much anything you want.
And of course like any developer, I get VERY tired VERY fast having to type connection string and code to get a data table from sql. So I have this "handy" helper bit of code I used above.
DataTable MyRst(string strSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
cmdSQL.Connection.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
(so adjust above to use your connection string)
So above should give you the "building" block you need.
So:
To get columns from a given GV row, use .cells[] colleciton.
To get "controls" you may well use in the GV, use find control.
to get row click, see the above button code.
With these 3 things, this should allow you to do just about anything you ever want to do with a GV.
Edit: Get/find a rowindex on a column value - in this case ID
Ok, so really, we want to search/find and obtain the row index from the GV for a given value in the GV - in this case, for a given "ID" value, we want the row index.
AGAIN, context matters. Maybe this is a row click in client side JavaScript code, but as the question is written, then we looking to find the row index for a given ID.
ok, this will work:
Function GetRowIndex(sFind As String, sKey As String, GV As GridView) As Integer
For Each gRow As GridViewRow In GV.Rows
If GV.DataKeys(gRow.RowIndex).Item(sKey) = sFind Then
Return gRow.RowIndex
End If
Next
Return -1
End Function
So, there is no built in translation here.
The REAL issue, is when, where, why you want the row index based on say a given datakey. I been doing this for OVER 10 years, and have NEVER needed to do this.
In other words? DO NOT try and use the gridview as a database, or some "thing" that stores data - it is mostly for display, and if you need to search, then provide a grid search ability, and filter the results.
So, you can search values in the Grid, or values (not displayed) in datakeys.
So, this routine would return the row index for a given data key value. HOWEVER, do NOT just SHOVE general values into datakeys - in 99% of cases, datakeys is for the ONE database primary key value, and those values should NOT be exposed to the end user - they NEVER are to see the database key values - especially with web based software (too high of a security risk).
So, this routine would search datakeys:
Function GetRowIndex(sFind As String, sKey As String, GV As GridView) As Integer
For Each gRow As GridViewRow In GV.Rows
If GV.DataKeys(gRow.RowIndex).Item(sKey) = sFind Then
Return gRow.RowIndex
End If
Next
Return -1
End Function
However, if the data is in the GV, then search that, and does not "needless" add the values to the datakeys (only have/place values in datakeys that you don't want to display or expose to the end user).
So, in above, I can do this:
Dim sFindID As String
sFindID = "5"
Debug.Print($"Row index of given id {sFindID} = {GetRowIndex(sFindID, "ID", GVHotels)}")
I have this DropDownlist Screenshot:
and what I want to do is to change the displayed text of the DropDownList based on the selected table row. I have this code below but it is not working. I am using C# and ASP.NET btw.
C# Code:
drpDepartment.DataTextField = grdRecentCases.SelectedRow.Cells[1].Text;
drpCharge.DataTextField = grdRecentCases.SelectedRow.Cells[2].Text;
You can use Text to change the value of the 2 drop downs (ddl, drop down list), but ONLY if the ddl's downs are SINGLE column drop downs. If the dropdown has TWO columns, and they OFTEN do, such as "ID" and Department, but you ONLY display the department text, but the first "id" column drives the dropdown?
Then when ddl has or is bound to two columns, then you MUST set the Text value by the "ID" (the hidden column of the ddl).
In your case, it looks like you ONLY have the "text" from the grid, and thus you have to use a .find in the ddl for this purpose.
Example:
This data for drop hotels:
So, our markup:
<h3>Select Hotel</h3>
<asp:DropDownList ID="drpHotels" runat="server"
DataValueField="ID"
DataTextField="HotelName"
AppendDataBoundItems="true" Width="130px" >
<asp:ListItem Text="Select" Value="0"></asp:ListItem>
</asp:DropDownList>
And our code to load:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadDrops();
}
void LoadDrops()
{
DataTable rstOptions =
MyRst("SELECT ID, HotelName FROM tblHotelsA ORDER BY HotelName");
drpHotels.DataSource = rstOptions;
drpHotels.DataBind();
}
And now we have this:
So, in code behind, say I want to set the ddl to "Swiss Village"?
I can NOT go
drpHotels.Text = "Swiss Village"
(the ddl has TWO columns).
However, I CAN go:
drpHotels.Text = "6"; // Swiss Village PK (id) is 6 from table
So, you have a choice here:
You can either take the text value, query the database based on that real text value from the grid, translate into a "id", and shove that into the text property.
Or, you can do a "find" on the ddl like this based on the text value.
string strTest = "Swiss Village";
drpHotels.ClearSelection();
drpHotels.Items.FindByText(strTest).Selected = true;
So, either you set the ddl by the "id" or first hidden column you have, or you use the above to "find" the item by the "text" value (2nd column) as per above.
I have a DataTable which I have created in code file and I later bind it to a GridView which i have created by using the drag and drop feature of Visual studio.
However I have added some columns in the GridView which are not supported(correct me if I am wrong) in a DataTable, e.g Hyperlink-Column or CheckBox-Column.
I would like to build the hyperlink column and the checkbox id's with a value derived from a value generated in the DataTable from a particular column. I know I can use DataNavigateUrlfields to build dynamic links but how do I do this with a DataTable that is to be bound later?
I also need the columns in the GridView to appear after the columns in the DataTable.
Any help in the above will be highly appreciated. Any alternatives are also appreciated.
Declaratively added controls will be created first and then the databound/manually created(documented in the Page's Lifecycle, search for "controls created declaratively"). Since you want the declarative columns last, you need a hack:
You could use RowDataBound to change the order, so that the AutoGenerated columns are followed by your other columns like Hyperlink or CheckBox columns:
protected void gridOffers_RowDataBound(object sender, GridViewRowEventArgs e)
{
TableCell cell = e.Row.Cells[0];
e.Row.Cells.RemoveAt(0);
//Move first to the end
e.Row.Cells.Add(cell);
cell = e.Row.Cells[0];
e.Row.Cells.RemoveAt(0);
//Move second to the end
e.Row.Cells.Add(cell);
}
However I have added some columns in the GridView which are not
supported(correct me if I am wrong) in a DataTable, e.g
Hyperlink-Column or CheckBox-Column.
They don't need to be supported in the DataTable but in the GridView. The table contains your data and the grid contains the view.
You can try with this code - based on RowDataBound
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server" Text=""></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
You can adjust you datbound with your event RowDataBound, i added HyperLink control, in order to customize your link as you want.
void GridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
var hyperLink = (HyperLink)e.Item.FindControl("HyperLink1");
hyperLink.NavigateUrl ="....";
var checkBox = (CheckBox)e.Item.FindControl("CheckBox1");
checkBox.Checked =....
}
}
Well there is an easy way to append a column if you are using datatable
DataTable yourDataTable = new DataTable();
Load yourDataTable by DataReader or DataAdapter
DataColumn newColumn = yourDataTable.Columns.Add("Total", typeof(Int32));
After that you can bind this datatable into your Gridview.
msdn
i am trying to develop one application, the data displayed in Gridview. gridview contains many boundfield colums . I recently add a column after the end of last boundfield column of gridview (Imported boundfield column). so i have less chance to move the last boundfield to desired location in mark up. if i move the column to desired place, then i've to modify entire coding while row _databounding. so is there any way we can re order the columns without changing in mark up ?? ..
<asp:BoundField DataField="someData" HeaderText="SomeData"> </asp:BoundField>
<asp:CommandField UpdateText="Update" EditText="Edit" CancelText="|Cancel" ShowEditButton="true" ControlStyle-CssClass="LinkNormal" />
<asp:BoundField DataField="someData2" HeaderText="Imported"> </asp:BoundField>
out put will be like this (EDit/Delete/Imported are boundfield columns )
SomeData | Update| Imported
what i need now gridview shoud display like this
Imported | SomeData | Update
I would suggest moving away from using column indexes, and start using data keys to reference column values in the code-behind. That way, you can change the markup and move columns around without effecting the code-behind.
<asp:GridView ID="GridView1" runat="server" DataKeyNames="Col1, Col2, Col3" ... >
Using data keys, you can get column values like this in the RowDataBound event:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
string col1 = GridView1.DataKeys[e.Row.RowIndex]["Col1"].ToString();
}
It seems, that GridView hasn't such functionailty. Instead of, you can try to obtain indexes of columns in code behind by for example column's header text, below is such function that does the job:
int getColumnIndexByHeaderText(GridView gridView, string headerText)
{
for (int i = 0; i < gridView.Columns.Count; ++i)
{
if (gridView.Columns[i].HeaderText == headerText)
return i;
}
return -1;
}
And use it instead of hardcoded column indexes.
I have a gridview that is displaying data from a database using LINQ to SQL.
AssetDataContext db = new AssetDataContext();
equipmentGrid.DataSource = db.equipments.OrderBy(n => n.EQCN);
I need to add a column at the end of the girdview that will have links to edit/delete/view the row. I need the link to be "http://localhost/edit.aspx?ID=" + idOfRowItem.
Try adding a TemplateField to your GridView like so:
<Columns>
<asp:TemplateField>
<ItemTemplate>
Edit
</ItemTemplate>
</asp:TemplateField>
</Columns>
Within the item template you can place any links you like and bind any data you wish to them from your DataSource. In the example above I have just pulled the value from a column named id.
As things stand this would work fine, however the column above would be aligned left most in the GridView with all the auto generated columns to its right.
To fix this you can add a handler for the RowCreated event and move the column to the right of the auto generated columns like so:
gridView1.RowCreated += new GridViewRowEventHandler(gridView1_RowCreated);
...
void gridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
GridViewRow row = e.Row;
TableCell actionsCell = row.Cells[0];
row.Cells.Remove(actionsCell);
row.Cells.Add(actionsCell);
}
Hope this helps.