I have a DataTable which has columns that are generated dynamically at runtime. This DataTable is bound to a GridView that has AutoGenerateColumns set to true. I've run into a problem with this since some of the data in the DataTable are HyperLink objects, so instead of displaying the actual link in the table, it displays "System.Web.UI.WebControls.HyperLink".
Normally, I would just use a HyperLinkField in my GridView, but since the GridView's columns are generated automatically, I'm not sure how to do this. Any ideas?
You can add a new column dynamically, you'll just have to hide the automatically generated columns also.
For this solution you can either store the hyperlink in 2 columns - 1 for the link and 1 for the text you want displayed, or if you want something generic displayed (like 'Click Here') you can just store the link (eg "http://example.com.au/Default.aspx").
protected void GridView1_RowBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
//add new header
TableCell tc = new TableCell();
tc.Text = "Groovy Link";
e.Row.Cells.Add(tc);
//hide original column that has been autobound - skip column we just added
for (int i = 0; i < e.Row.Cells.Count - 1; i++)
{
BoundField field = (BoundField)((DataControlFieldCell)e.Row.Cells[i]).ContainingField;
if (field.DataField == "AutoGeneratedColumnName")
field.Visible = false;
}
}
else if (e.Row.RowType == DataControlRowType.DataRow)
{
//create new tablecell
TableCell tc = new TableCell();
//do a check to see if the data is stored as a hyperlink in DB
if (DataBinder.Eval(e.Row.DataItem, "AutoGeneratedColumnName").ToString().StartsWith("<a") == true)
{
//create hyperlink
HyperLink hyp = new HyperLink();
hyp.NavigateUrl = DataBinder.Eval(e.Row.DataItem, "AutoGeneratedColumnName").ToString();
hyp.Text = "click here";
tc.Controls.Add(hyp);
}
else
{
//just text
tc.Text = DataBinder.Eval(e.Row.DataItem, "AutoGeneratedColumnName").ToString()
}
//add tablecell to row
e.Row.Cells.Add(tc);
//hide original column that has been autobound
for (int i = 0; i < e.Row.Cells.Count - 1; i++)
{
BoundField field = (BoundField)((DataControlFieldCell)e.Row.Cells[i]).ContainingField;
if (field.DataField == "AutoGeneratedColumnName")
field.Visible = false;
}
}
}
Related
I have an ASP.NET web app that processes some data from other sites and displays the information in a gridview. I don't know how many rows that gridview is going to have, nor how many columns.
In this gridview I have a templatefield which I used to add a Checkbox.
The rest of the columns are added using a DataTable that I bind to this gridview. The problem now is that after 10 columns, I have an URL which I want to display as a button, or a link. After this link I have x nr of columns.
How do I add this URL which is resting between static columns and dynamic columns, in a GridView with dynamic rows ?
I tried writing a href=link.. in the DataTable but it displays it as text.
I found an article that suggested something with HtmlDecode, but for that to work I would need to use boundfields which set the htmlencode = false..or something like that.
Is there any way of doing this ? or should I just move the link in the itemtemplate that has the checkbox as well and try to set it there ?
You can use the MatchGrid_RowDataBound method to look over the columns and add the buttons as you need.
Here is an example of how to add a button on RowDataBound:
How do I programmatically add a button to a gridview and assign it to a specific code-behind function?
You can use the OnRowDataBound for that. It will insert extra cells into the GridView. You could also insert extra column into the DataTable before binding it to the GridView.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
//header
if (e.Row.RowType == DataControlRowType.Header)
{
//add 6 cells
for (int i = 1; i <= 6; i++)
{
TableHeaderCell headerCell = new TableHeaderCell();
if (i == 6)
{
headerCell.Text = "URL";
}
else
{
headerCell.Text = "Static " + i;
}
//add the new cell to the gridview
e.Row.Cells.AddAt(i, headerCell);
}
}
//normal row
if (e.Row.RowType == DataControlRowType.DataRow)
{
//cast the current row to a datarowview
DataRowView row = e.Row.DataItem as DataRowView;
//add 6 cells
for (int i = 1; i <= 6; i++)
{
TableCell cell = new TableCell();
if (i == 6)
{
cell.Text = string.Format("<a target=\"_blank\" href=\"{0}\">{0}</a>", row["myURL"]);
}
else
{
cell.Text = "Enter stuff here...";
}
//add the new cell to the gridview
e.Row.Cells.AddAt(i, cell);
}
}
}
I used #Tim Schmelter code (Creating Gridview column Header by loading data from database) for ItemTemplate Checkboxes its working fine but when use HeaderTemplate, I'm getting an error at ITemplate --> CB_DataBinding --> object dataValue = ((DataRowView)container.DataItem)[_columnName]; saying NullReference since DataItem is Null. MyCode:
private void CreateGridColumns()
{
var tblAllowanceGroup = GetAllowanceGroup();
foreach (DataRow row in tblAllowanceGroup.Rows)
{ ...
field.HeaderTemplate = new GridViewCheckBoxTemplate(ListItemType.Header, AllowanceGroupName);
gvEmpSalaryStructure.Columns.Add(field);
}
private void BindGrid()
{
var tblAllowanceGroup = GetAllowanceGroup();
DataSet dsgrid = new DataSet();
DataTable dtgrid = new DataTable();
var empRow = dtgrid.NewRow();
dtgrid.Columns.Add("EmpName");
foreach (DataRow row in tblAllowanceGroup.Rows)
{
String AllowanceGroupName = row.Field<String>("AllowanceName");
//Add column from domain-name
dtgrid.Columns.Add(AllowanceGroupName, typeof(bool));
//CheckBox-Checked is a boolean
//This gives me only Header Text of Gridview
}
I Want GridView dynamically generated Headers which should contain Checkboxes. And want changes should I Make ITemplate CB_DataBinding to work with ListItemType.Header.
And When we check the checkbox in the Header column all the checkboxes in that column should be checked.
Thanks in Advance.
You can use the OnRowDataBound event of the gridview to loop the header row and insert a CheckBox in each Cell.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
for (int i = 0; i < e.Row.Cells.Count; i++)
{
CheckBox checkBox = new CheckBox();
checkBox.CssClass = "headerCheckBox";
checkBox.ID = "headerCheckBox_" + i;
e.Row.Cells[i].Controls.Add(checkBox);
}
}
}
And now you can bind a jQuery listener to the CheckBox class to handle the checking/unchecking of the entire column.
When I load the page I send the number of rows the table will have:
protected void Page_Load(object sender, EventArgs e)
{
string numFilas = Request.QueryString["filas"];
tblAdd.Visible = true;
for (int i = 0; i < int.Parse(numFilas); i++)
{
TableRow NewRow1 = new TableRow();
TableCell NewCell1 = new TableCell();
TableCell NewCell2 = new TableCell();
TextBox txtBox1 = new TextBox();
txtBox1.Width = 200;
TextBox txtBox2 = new TextBox();
txtBox2.Width = 200;
// adding lebel into cell
NewCell1.Controls.Add(txtBox1);
NewCell2.Controls.Add(txtBox2);
// adding cells to row
NewRow1.Cells.Add(NewCell1);
NewRow1.Cells.Add(NewCell2);
tblAdd.Rows.Add(NewRow1);
}
}
now when I click submit I'd like to retrieve the data of the textbox inside the table, what I've been capable of is this:
public void submit(Object sender, EventArgs e)
{
for (Int32 i = 0; i < tblAdd.Rows.Count; i++)
{
TableRow dr = tblAdd.Rows[i];
TableCell hhh = dr.Cells[0];
String textCell = hhh.Text();
}
}
However, the text in the cells is empty because the text the user writes is IN the textbox, which I don't know how to get it.
Try this
While creating your text boxes add an ID
E.g.
txtBox1.ID = "txtBox1";
Then you can easily find this TextBox control from the current Cell's Controls collection as follows.
string textCell = ((TextBox)dr.Cells[0].FindControl("txtBox1")).Text;
Hope you understood what I'm trying to say. Basically, you need to find your control in the Cell.
Vote and accept the answer if it solved your issue.
Cheers!
i need to convert a field in gridview to a dropdownlist,
but i need to do this in codebehind, and I cannot add a templatefield in apsx(but it could be created at run time execution...)
I populate my grid with this code:
foreach (var item in response.Select(x => x.idMatriz).Distinct())
{
dr = dt.NewRow();
for (int i = 0; i < colunas; i++)
{
dr[i] = response.Where(x => x.Propriedade == dt.Columns[i].ToString() && x.idMatriz == item).Select(x => x.Valor).FirstOrDefault();
}
dt.Rows.Add(dr);
}
It works but i need this fileds be a dropdown....
any help?
It looks like all you need to do is dynamically create a template field and add it to the gridview.
var field = new TemplateField {HeaderText = col.ColumnName}
gridView.Columns.Add(field);
After that, on the row created event of the gridview create and wire up the dropdown.
public void DynamicGridView_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType != DataControlRowType.DataRow)
{
return;
}
var grid = sender as GridView;
if (grid == null)
{
return;
}
for (var i = 0; i < grid.Columns.Count; i++)
{
var column = grid.Columns[i] as TemplateField;
if (column == null)
continue;
var cell = e.Row.Cells[i];
var dropdown = new DropDownList();
cell.Controls.Add(dropdown);
}
}
I have added gridview that is binds with csv file data that stored in session variable like this:
dgData.DataSource = Session["csvdata"];
dgData.DataBind();
It binds perfectly.But i need to add dropdownlist at first row of gridview for mapping of database column name with grid header.I used this code to add dropdownlist.But dropdown added to header instead of first row.
protected void dgData_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header )
{
for (Int32 i = 0; i < e.Row.Cells.Count; i++)
{
DropDownList ddl = new DropDownList();
ddl.ID = "ddlCol" + i.ToString ();
e.Row.Cells[i].Controls.Add(ddl);
}
}
}
protected void dgData_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl;
if (e.Row.RowIndex == 0)
{
for (Int32 i = 0; i < e.Row.Cells.Count; i++)
{
ddl = new DropDownList();
ddl.ID = "ddlCol" + i.ToString ();
e.Row.Cells[i].Controls.Add(ddl);
}
}
}
}
this code add's control to exatly first row of grid-view