I'm creating a dynamic GridView from a DataTable that is returned from a stored procedure. I call and bind with the following code:
DataTable dt = Sql.reportData(Convert.ToInt32(Session["userID"]));
this.GridView1.DataSource = dt.DefaultView;
this.GridView1.DataBind();
I need to restyle certain columns but they are not always the same column number, and only have the headers text string to identify it. Is there an easy way to track a column down like this so I can edit its attributes?
Thanks,
Alex
I've run into this myself. You've got to loop through the column names, get the index, and then refer to the index to manipulate the style.
Muhammad is right about the timing, but you won't be searching for a label--it seems you want to style the entire column, right?
http://forums.asp.net/p/1076872/1584635.aspx
the above has several versions of a solution.
The best place to find the control and use it will be in the RowCreated event. RowDataBound should not be used because you dont have to manipulate the data with which the column is being binded. So restyle the elements in the column by searching them in the RowCreated event.
protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
e.Row.FindControl("");
}
Related
Just wanted to know if this is possible with C#.
I have a GridView. The Datasource of the GridView is a DataTable generated from a Database. The AutoGenerateColumn is True.
Therefore when I try the following code
gridView.Columns.RemoveAt(1); //I got 12 Columns from the DataTable
I get the following error:
Exception Details: System.ArgumentOutOfRangeException: Index was out
of range. Must be non-negative and less than the size of the
collection.
I don't want to delete it from the DataTable. I want to delete the column before I use RenderControl to convert the GridView to html text. And I don't want the column to show up in html text. I tried doing this too:
foreach (GridViewRow row in gv.Rows){
row.Cells[1].Visible = false;
}
But it doesn't hide the Column Header.
Anyone have any idea if it is possible to delete column?
Try this
gridView.columns.RemoveAt(1);
gridView.Databind();
Try this: On GridView1.RowDataBound event
GridView1.Columns(0).Visible = False
OR
protected void bla_RowCreated(object sender, GridViewRowEventArgs e)
{
e.Row.Cells[0].Visible = false; // hides the first column
}
Actually, RowCreated will be called several times each time the GridView renders. But it works
Is there a way to access elements that are in another row, while you're in a RowDataBound event?
public void gridview1_RowDataBound(object sender, GridViewRowEventArgs e)
{
// how to compare e.Row with row above or row below?
}
One thing I think you can do is...
foreach (GridViewRow gvrow in GridView1)
{
//loop through gridview's rows and find the row you're looking for
}
I believe that RowDataBound adds the rows in the same order that the data source has them in, therefore if there are 100 records in your DataTable and you bind that DataTable to the GridView, RowDataBound gets called 100 times, for each row, in the order they exist in the DataTable. Therefore, you mentioned using RowDataBound to compare e.Row with the row above OR row below...but if they are coming in sequentially, there is no row below. This is something I hadn't really thought about before but I recall when doing testing with breakpoints that RowDataBound functions in this manner.
If you can't get something like that working, and you need this to happen even if it isn't pretty and don't get any better answers, you can store a copy of your databound DataTable or whatever your source for data is into a ViewState or Session variable, like ViewState["myDataTable"]. You can then retrieve the DataTable on RowDataBound event, and look at the rows above and below the row that is represented by e.Row (provided that you have some kind of cursor like an ID to identify the rows). By doing this, you CAN look at the next row that will be added to the GridView by RowDataBound, because it will be the next row in the DataTable (which already exists and can be viewed).
If you're doing stuff on a massive scale though, I imagine all this looping could get cumbersome.
From a foggy memory, you can reference GridView's array of Rows from there and iterate them. You should be able to get e's position and access in any case the rows above, not sure about rows below as they aren't databound by then yet I suppose, unless this is a one-row rebind shot.
I need to find and display the number of rows returned by the query. This query is made using an SQLDataSource object, which is bound to an asp.net GridView control. How can I find this information?
You can't use the Rows property on the grid, because that only gives you what the GridView is currently rendering. You need to hook up to the Selected event on the SqlDataSource and then you can pull the AffectedRows property.
protected void SqlDataSource1_Selected(object sender, SqlDataSourceStatusEventArgs e) {
int totalRows = e.AffectedRows;
}
I would suggest that you handle the SQLDataSource.Selected event and check the e.AffectedRows property. It returns the number of selected rows. Also, it is possible to obtain this information programmatically:
DataView dv = (DataView)SQLDataSource1.Select(DataSourceSelectArguments.Empty);
int rowCount = dv.Count;
NOTE: this code will result in selecting data once again. So, the best solution is to use the Selected event for this purpose.
I have an empty GridView object on a page that I bind to a LINQ qry result at run time. The GridView has a 'Select" button that fires the SelectedIndexChanged event and it's inside of this event that I'd like to access the data of one of the fields in the selected row.
So far, I can only find one way to do this, and it seems suboptimal:
protected void GridView2_SelectedIndexChanged(object sender, EventArgs e)
{
GridViewRow row = GridView2.SelectedRow;
string UserID = row.Cells[1].Text;
//Do stuff with the userID
}
So this just access the cell data directly based on the cell index. The UserID just happens to be in the second cell and so it works. But later down the road, the UserID may not be in that same column. It seems like I'd be better off looking up the value of this cell by accessing by the cell's header name, or by any method other than the cell index itself.
Any ideas?
Thanks!
Try this
User user = (User)((DataRowView)row.DataBoundItem).Row;
int userID = user.UserID;
I am assuming you have a class called User and you are binding the DataGridView to may a List
I don't know much about asp.net, but in the C# DataGridView you can index columns directly by column name, i.e.
string UserID = row.Cells["UserID"].Text;
or something like that. Might be worth a try.
You can use following code to retrieve object bound to current SelectedRow.
DataTable dt = (DataTable)<GridViewControl>.SelectedRow.DataItem
(here I have assumed that Grid is bound with DataTable.)
I'm trying to add HyperLinkColumns dynamically to my GridView. I have the following code:
HyperLinkColumn objHC = new HyperLinkColumn();
objHC.DataNavigateUrlField = "title";
objHC.DataTextField = "Link text";
objHC.DataNavigateUrlFormatString = "id, title";
objHC.DataTextFormatString = "{2}";
GridView1.Columns.Add(objHC);
This doesn't work, so.. how can i add a HyperLinkColumn to my GridView?
You might want to add it when the row is binded:
protected void yourGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
HyperLink hlControl = new HyperLink();
hlControl.Text = e.Row.Cells[2].Text; //Take back the text (let say you want it in cell of index 2)
hlControl.NavigateUrl = "http://www.stackoverflow.com";
e.Row.Cells[2].Controls.Add(hlControl);//index 2 for the example
}
You have to do it before the DataBinding takes place, check the GridView Events.
I think you should be using a HyperLinkField not a HyperLinkColumn.
In case, if you just want to redirect to another URL then simple use HyperLink web control and push it in the desired cell of GridView Row at RowDataBound event.
OR
If you want to perform any server event before sending it to another URL, try this
1) Add LinkButton object at RowDataBound event of GridView.
2) Set the CommandName, CommandArgument property, if requried to pass any data to this object.
3) Capture this event by handling the RowCommand event of the GridView.
By the way, I just think that you can use the DataGridView and in the Designer select the Link column and your problem would be over. The DataGridView does have a link column, than you just need to add an event on "Click" and you will be able to have what you want. This solution works if you can switch to DataGridView.
I know this thread is old but couldn't help adding my 2 cents. The procedure explained in the following tutorial worked perfectly for me:
ASP Alliance
It seems you have got things mixed up. I don't know - how that code compiles?
GridView's column collection can accept columns of type "DataControlField".
I think you need to initialize HyperLinkField and set relevant properties (text, NavigateUrl, HeaderText, Target) and add it to the columns collection.
HyperLinkColumn class is meaningful when you are using DataGrid (not in case of GridView).
Hope that helps.