I have a gridview and need to add controls to header row. I am able to add text, but how can I add a hyperlink to the header row.
protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
GridView HeaderGrid = (GridView)sender;
GridViewRow HeaderGridRow = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Insert);
TableCell HeaderCell = new TableCell();
HeaderCell.Text = "Logistics Details";
HeaderCell.ColumnSpan = 2;
HeaderGridRow.Cells.Add(HeaderCell);
GridView1.Controls[0].Controls.AddAt(0, HeaderGridRow);
HyperLink hl = new HyperLink();
hl.ID = "hlDetail";
hl.Text = "Details";
//the below line doesn't add controls
HeaderGridRow.Controls.Add(hl);
}
}
I think you would have to add the control to a specific Cell within the row, e.g.
HeaderGridRow.Cells[0].Controls.Add(hl);
Since it's a grid, it's not logical for items to exist within a row outside a cell - then there is no way to know where exactly to display it.
You probably also need to set the NavigateUrl property of the Hyperlink, otherwise it does not know where to navigate e.g.
hl.NavigateURL = "https://www.google.com"
Related
why doesn't the cell i just added to a row get found with FindControl()?
// cell
var cell = new System.Web.UI.WebControls.TableCell();
cell.ID = "cell";
// cell in row
var row = new System.Web.UI.WebControls.TableRow();
row.Controls.Add(cell);
// get cell from row
var foundCell = row.FindControl(cell.ID);
foundCell becomes null
To FindControl a dynamic item that created from back-end programming code, asp.net need to post_back to add the Control to DOM.
In your case, you need to separate your Adding Control function and Finding Control function in different asp.net life-cycle.
First, Create the Control in Page_Init:
public void Page_Init(object sender, EventArgs e)
{
// cell
var cell = new System.Web.UI.WebControls.TableCell();
cell.ID = "cell";
// cell in row
var row = new System.Web.UI.WebControls.TableRow();
row.Controls.Add(cell);
}
Then you can find the Control in Page_Load:
protected void Page_Load(object sender, EventArgs e)
{
// get cell from row
var foundCell = Page.FindControl("cell"); // or you can store the cell Id in a string variable
}
You can find more info on MSDN, on the ASP.NET Page Life Cycle article.
row.findControl(cell.ID) is not working in your case and you can replace it with below logic and its working fine.
var foundCell = row.Cells[row.Cells.GetCellIndex(cell)];
protected void gvDispMsg_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
GridView hGrid = (GridView)sender;
GridViewRow gvrRow = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Insert);
TableHeaderCell tcCellSub1 = new TableHeaderCell();
tcCellSub1.Controls.Add(lblDDLBlank);
gvrRow.Cells.Add(tcCellSub1);
gvDispMsg.Controls[0].Controls.AddAt(0, gvrRow);
LinkButton btnSort;
System.Web.UI.WebControls.Image image;
//iterate through all the header cells
foreach (TableCell cell in e.Row.Cells)
{
//check if the header cell has any child controls
if (cell.HasControls())
{
//get reference to the button column
btnSort = (LinkButton)cell.Controls[0];
image = new System.Web.UI.WebControls.Image();
if (ViewState["sortExp"] != null)
{
//Do something
}
}
}
}
}
I am getting the following error in line btnSort = (LinkButton)cell.Controls[0];:
Unable to cast object of type 'System.Web.UI.LiteralControl' to type 'System.Web.UI.WebControls.LinkButton'.
How can I resolve the error.
I know this is an old question, but in case someone finds it in a search in the future this is the correct way to cast a link button from a grid view:
var btnSort = (LinkButton)GridView1.Rows[i].Cells[k].Controls[1];
I have a GridView which holds user data. When the Page_Load Method is called, I get data using a DataTable and then bind it to the GridView. At the end of each row, I have added a CheckBox. This CB is used as a pointer for which entity the user wants to edit.
My problem is the Check_Changed Event of the CheckBoxes. I do not know how to add a handler if the control is generated programmatically. I also need the index of the row (a field value is also possible, but the column header and the column itself are hidden).
foreach (GridViewRow gvr in grdMitgliedsliste.Rows)
{
//add checkbox for every row
TableCell cell = new TableCell();
CheckBox box = new CheckBox();
cell.Controls.Add(box);
gvr.Cells.Add(cell);
//Hide columns for userid, status, etc.
gvr.Cells[0].Visible = false;
gvr.Cells[3].Visible = false;
gvr.Cells[4].Visible = false;
gvr.Cells[5].Visible = false;
gvr.Cells[8].Visible = false;
gvr.Cells[9].Visible = false;
}
I have already tried implementing the handler from here, but it gives me no index argument so the program cannot determine in which row the checkbox was checked.
protected void Page_Load(object sender, EventArgs e)
{
List<string> names = new List<string>();
names.Add("Jhonatas");
this.GridView1.DataSource = names;
this.GridView1.DataBind();
foreach (GridViewRow gvr in GridView1.Rows)
{
//add checkbox for every row
TableCell cell = new TableCell();
CheckBox box = new CheckBox();
box.AutoPostBack = true;
box.ID = gvr.Cells[0].Text;
box.CheckedChanged += new EventHandler(box_CheckedChanged);
cell.Controls.Add(box);
gvr.Cells.Add(cell);
}
}
void box_CheckedChanged(object sender, EventArgs e)
{
string test = "ok";
}
TableCell cell = new TableCell();
CheckBox box = new CheckBox();
box.Check += new EventHandler(Checked_Changed);
cell.Controls.Add(box);
gvr.Cells.Add(cell);
sorry, im allready about to drive home so its just an fast answer.
mabye you have to correct the event after box."event" ...
You should go this way:
first of all when you are generating the checkbox
CheckBox box = new CheckBox();
box.AutoPostBack=true;
provide an id to the checkbox as
box.ID=Convert.toString(Session["Count"]);
do initialize the "Count" when the page loads in the session.
also increment the "Count" everytime you add a new checkbox.
secondly, define the event handler for your dynamic check box like this:
box.CheckedChange += MyHandler;
and define the MyHandler
protected void MyHandler(object sender, EventArgs e)
{
//Do some stuff
}
now you may get the id for the checkbox from which the event has been fired inside the MyHandler, which will actually be the row number.
CheckBox cb = (CheckBox)sender;
string id = cb.ID;
I encountered a problem in Gridview, I cannot merge the headers if the Gridview has no record, but if the Gridview contain a record, the headers are merging.
Here is my codes that I used to merge the headers in the Gridview
protected void grdWorkExperience_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
GridView oGridView = (GridView)sender;
GridViewRow oGridViewRow = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Insert);
TableCell oTableCell = new TableCell();
oTableCell.Text = string.Empty;
oTableCell.ColumnSpan = 2;
oTableCell.BorderColor = System.Drawing.Color.White;
oGridViewRow.Cells.Add(oTableCell);
oTableCell = new TableCell();
oTableCell.Text = "Inclusive Dates(mm/dd/yyyy)";
oTableCell.ColumnSpan = 2;
oTableCell.Font.Bold = true;
oTableCell.Font.Size = 9;
oTableCell.Font.Name = "Verdana";
oTableCell.HorizontalAlign = HorizontalAlign.Center;
oTableCell.BackColor = System.Drawing.Color.FromArgb(0x33, 0x66, 0xCC);
oTableCell.ForeColor = System.Drawing.Color.White;
oTableCell.BorderColor = System.Drawing.Color.Gray;
oGridViewRow.Cells.Add(oTableCell);
oTableCell = new TableCell();
oTableCell.BorderColor = System.Drawing.Color.White;
oTableCell.ColumnSpan = 13;
oGridViewRow.Cells.Add(oTableCell);
oGridView.Controls[0].Controls.AddAt(0, oGridViewRow);
}
}
I placed that function in onRowCreated event of Gridview
What should I do to merge the Headers even if the Gridview has no record?
Move the code from OnRowCreated event to Load event of the Window/Control/Page
I'm currently having a problem with event handlers assigned in the code-behind not appearing in the HTML code of the .aspx page. Below is the code fragment that does that:
HtmlTable table = new HtmlTable();
HtmlTableRow row = new HtmlTableRow();
foreach(XmlNode item in IDList)
{
LinkButton btn = new LinkButton();
btn.Text = item.InnerText;
btn.Click += new EventHandler(btn_Click);
HtmlTableCell cell = new HtmlTableCell();
cell.Controls.add(btn);
row.cells.add(cell);
}
table.rows.add(row);
Something like that, more or less. So when I run the page and inspected the buttons using FireBug, I noticed that the eventhandler names for the buttons created have been changed to the LinkButtons' unique ID(ct125, 126, 127, etc), I think, and not "btn_Click"
I'm hoping to hear if anyone else has faced this problem before and found a solution for it. Thanks.
your buttons might be using submit behavior for your buttons. Try setting "UseSubmitBehavior=false" for the buttons.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.button.usesubmitbehavior.aspx
When creating controls dynamically, you should assign them Id also, otherwise asp.net will auto-assign them ids like ctl{somenumber}. Also, you need to recreate these controls on each postback, otherwise your eventhandlers will not work.
I was able to get this code to work as expected. I dynamically add 4 LinkButtons and wire the Click event to a function btn_Click. When I click each link, they call the btn_Click method server-side:
protected void Page_Load(object sender, EventArgs e)
{
HtmlTable table = new HtmlTable();
HtmlTableRow row = new HtmlTableRow();
for (int loop = 1; loop < 5; loop++)
{
LinkButton btn = new LinkButton();
btn.Text = "Test " + loop.ToString();
btn.Click += new EventHandler(btn_Click);
HtmlTableCell cell = new HtmlTableCell();
cell.Controls.Add(btn);
row.Cells.Add(cell);
}
table.Rows.Add(row);
// Add the table to a placeholder.
phInputs.Controls.Add(table);
}
protected void btn_Click(object sender, EventArgs e)
{
// Do something to catch a breakpoint.
var x = 10;
}
Ok, I got it fixed, but I'm absolutely bewildered at why it got fixed this way.
{
HtmlTable table = new HtmlTable();
HtmlTableRow row = new HtmlTableRow();
int btnIndex = 0;
foreach(XmlNode item in IDList)
{
LinkButton btn = new LinkButton();
btn.Text = item.InnerText;
btn.Click += new EventHandler(btn_Click);
btn.ID = "Btn_Page" + btnIndex.ToString();
HtmlTableCell cell = new HtmlTableCell();
cell.Controls.add(btn);
row.cells.add(cell);
}
table.rows.add(row);
}
protected void Btn_Page_0(object sender, EventArgs e)
{
whatever eventhandler code
}
When I inspected the HTML again, the names of the event handler assigned to the buttons are still being changed to its ID.
<a id="Btn_Page_0" href="javascript:_doPostback('Btn_Page_0','')">
So for each of those buttons, their event handlers are changed to Btn_Page_0, Btn_Page_1, Btn_Page_2, etc.
Strange thing is, they all go back to the Btn_Page_0 event handler when clicked, instead of btn_click
So.....yeah. Kinda boggles my mind why it worked like this, but it works anyhow...