Add ASP Controls to a Table Dynamically - asp.net

Right now I have an ASP Table. I can add rows and cells to this table just fine. What I would like to do, is instead of the cell just displaying text, I would like to add a control. For example a Button.
Right now, my first thought on how to do this would be just to put the <ASP:Button ... as the .Ttext attribute of the table cell. But my gut tells me this wont work. Further more, I probably couldn't add a function to handle the button click.
Can someone help point me in the right direction on how to achieve this?

You need to add the control to the table cell. Just call the Controls.Add method on the cell and add your control. Below is a brief sketch that should point you in the right direction.
Button b = new Button();
c.Controls.Add(b);

The following assumes you have a blank ASP:Table on your page with some defined rows (just for show really).
protected void Page_Init(object sender, EventArgs e)
{
foreach (TableRow row in this.Table1.Rows)
{
foreach (TableCell cell in row.Cells)
{
Button btn = new Button();
btn.Text = "Some Button";
btn.Click += new EventHandler(btn_Click);
cell.Controls.Add(btn);
}
}
}
void btn_Click(object sender, EventArgs e)
{
((Button)sender).Text = "Just Clicked";
}

The question hangs on what the source is for your controls. Bar far, the most effective way to make this happen is through data binding, even if your data source is just the Enumerable.Range() function.
Failing that, you need to create an instance of your controls and add them to the Control's collection of the table cell they will belong in. You can just use the += syntax for adding event handlers. The trick here is that the code to create and add the button will need to run again on every postback, and it will need to run before the page_load phase of the asp.net life cycle.

Related

Posted data in gridview where I was added control dynamically

I added controls (i.e. template column) dynamically in grid view and click on button (post back) then grid view populated existing data (i.e.posted data) twice separated by
protected void Page_Init(object sender, EventArgs e)
{
//on init recreated controls
// if (IsPostBack)
{
gvFirst.DataSource = GetData("select top 10 * from Project_Master");
gvFirst.DataBind();
}
}
Sounds like you might be using Auto-generated fields. In design view, click the smart tag on the gridview and click "edit columns." Then uncheck the checkbox that says "Auto-generate fields." I think this should fix your problem if I am understanding you correctly.

asp:GridView doesn't contain control added in OnRowDataBound

I have problem, I can't get control which I added in DataGrid. I am adding it in OnRowDataBound event like:
protected void RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowState == DataControlRowState.Edit || e.Row.RowState == (DataControlRowState.Alternate | DataControlRowState.Edit))
{
//int cindex = 0;
//for (cindex = 0; cindex < e.Row.Controls.Count; cindex++)
foreach (Control ctl in e.Row.Controls)
{
DataControlFieldCell dcctl = (DataControlFieldCell)ctl;
TableCell tcell = (TableCell)dcctl;
Label lblComment = new Label();
TextBox txtComment = new TextBox();
lblComment.Text = "<br>Comment: ";
dcctl.Controls.Add(lblComment);
dcctl.Controls.Add(txtComment);
//tcell.Controls.Add(lblComment);
//tcell.Controls.Add(txtComment);
//e.Row.Cells[cindex].Controls.Add(lblComment);
//e.Row.Cells[cindex].Controls.Add(txtComment);
What is happening here: there is already exist one TextBox in TableCell by default and I want to add another one TextBox and Label. After the bounding I can see 2 textboxes, I can input data into the both, but when I click Update button, then raises OnRowUpdating event where I can't get my TextBox!
protected void RowUpdating(object sender, GridViewUpdateEventArgs e)
{
grdView.EditIndex = -1;
int counter = 0;
for (counter = 0; counter < grdView.Rows[e.RowIndex].Cells.Count; counter++)
{
foreach (Control ctl in grdView.Rows[e.RowIndex].Cells[counter].Controls)
{
And here I will be getting only default one TextBox (with its value). But my TextBox is disappeared! :(
What could you suggest me here to do?
P.S. I can't use predifined columns, like asp:TemplateField in aspx file, because my table has different amount of rows every time. It is dynamic
The issue is that after you dynamically add a control to a page (or any of the page's child controls such as your datagrid) then you must recreate the controls on the server side on postback. If you don't recreate the controls on the server side, then when the runtime processes the postback it will have no idea where to put the contents of the form post.
So essentially when the page is processing the postback, it sees an HTML field called "gridView1_txtComment" (the actual HTML id is probably something else, I know). But the server side code model only has an instance of gridView1, there isn't an instance of a TextBox named txtComment unless you run the RowDataBound method again to create that control.
I think it has to do with ViewState. Make a templated column out of it, then add the second textbox to the template.
I did it!
Refused of dynamically adding controls in OnRowDataBound, and created dynamical TempalteField columns, which were containing needed to me 2 TextBoxes and Label. (With help of http://www.codeproject.com/KB/aspnet/create_template_columns.aspx)
But after my problem returned back.. On OnRowUpdating event still was not having my added TextBoxes. Finally I've found here notice http://forums.asp.net/p/1537632/3738331.aspx, that it is needed to implement TempalteField-s adding on Page_Load, that helped me to solve the problem!

Hide Gridview Command Buttons

I have a gridview which has rows of 'tickets'. A user has the ability to 'claim' a ticket, this is all set up and works. What i need is to be able to change/hide the 'claim' button and replace it with a 'release' or 'open' command button. Can i achieve this at a rowdatabound level? What i do not want is to query the db everytime to see if the ticket is claimed.
You could cast the button from its Cell, then change its CommandName, and CommandArgs if needed, along with its text; eg use the same actual button for many purposes.
Im asssuming there is some status field that dictates what you can do with a record? Therefore on RowDataBound get this via a datakey, and adjust the button to suit.
Then on its click, check the command name and execute the relevant function / code block?
Edit - like this:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
Button btn = e.Row.Cells[YourButtonsColumIndex].FindControl("btnYourButtonsID") as Button;
btn.CommandName = "Release";
//Or
((Button)e.Row.Cells[YourButtonsColumIndex].FindControl("btnYourButtonsID")).CommandName = "Release";
}
Bearing in mind hidden rows still count in the zero-index column list.

gridview asp.net mouse over TR find which row was clicked on server side code

I am pretty new to the whole JavaScript thing. I have a gridview that I want the user to be able to hover over the whole row (believe its the whole TR) and be able to click anywhere and that would be able to select that row. I need the server-side code to be able to know which row was clicked.
I don't really know where to start with this and would love some guidance on:
Best way to add the ability to show that the user is hovering over a row (changing the background colour or something)
How to hook up the ability to click anywhere on that row and fire server-side code to know which row was clicked.
Was reading this article http://www.dotnetcurry.com/ShowArticle.aspx?ID=109 on firing server-side code from client-side but don't know how to figure out what row it would have come from.
This should do the trick, just make the gridview selectable
protected void Gridview1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes["onmouseover"] = "this.style.background = '#CCCCCC';";
e.Row.Attributes["onmouseout"] = "this.style.background = '#FFFFFF';";
e.Row.Attributes["onclick"] = ClientScript.GetPostBackClientHyperlink(this.Gridview1, "Select$" + e.Row.RowIndex);
}
}
The click will be detected server-side by the GridView click event.
I always work with repeater control, for hover effect on repeater i use jQuery
This goes between the <head> tags
$(document).ready(function() {
$(".tr-base").mouseover(function() {
$(this).toggleClass("trHover");
}).mouseout(function() {
$(this).removeClass("trHover");
});
});
and this is the CSS class.
.trHover{background-color: #D5E5ED;}
If you won't do anything in server-side when the row is clicked you can use jQuery again for the selected effect.

Postback destroys user controls in my GridView columns

I have a ASP.NET GridView that uses template columns and user controls to allow me to dynamically construct the datagrid. Now I'm implementing the event handler for inserting a row. To do that, I create an array of default values and add it to the data table which is acting as a data source. However, when my OnLoad event is fired on postback, all my template columns no longer have the user controls. My gridview ends up just being all blank with nothing in it and my button column disappears as well (which contains the add row, delete row and save buttons).
My row add event just does this:
public void AddDataGridRow()
{
List<object> defRow = new List<object>();
for (int i = 0; i < fieldNames.Count; i++)
{
defRow.Add(GetDefaultValueFromDBType(types[i]));
}
dt.Rows.Add(defRow);
}
It is fired from a button in a user control that's implement like this:
protected void Button1_Click(object sender, EventArgs e)
{
((Scoresheet)(this.Page)).AddDataGridRow();
}
My on load event does a bunch of stuff on first run to set the GridView up but I don't run that again by using the IsPostBack property to tell.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
Initialize();
}
Anyone have any hints as to why my user controls are vanishing?
You have to add the controls to the grid on every page_load, not just if it's (!Postback)
Do you have the EnableViewState=true on the usercontrols and the GridView?
Is the AddDataGridRow() method called by Initialize()? You basically have two options:
Bind the grid on every postback and do not use viewstate (performace loss)
Bind the Grid only the first time (if (!IsPostBack)), and make sure that your user controls keep their viewstate.
From your code, it is not clear whether the user controls keep viewstate and what they have in them. It is not even clear what is the execution order of the methods you've shown. There is no binding logic, so even if you keep adding rows, the grid may still not be bound. Please elaborate a bit and show the whole page codebehind.

Resources