I want to handle click event of link button which is dynamically created.
But i am not getting btn.click for it.
I have following code:
Public Sub test()
Dim row As New HtmlTableRow()
Dim cell As New HtmlTableCell()
For i = 0 To 10
row = New HtmlTableRow()
For j = 0 To 3
cell = New HtmlTableCell()
cell.InnerText = "m"
Dim btn1 As New LinkButton
btn1.ID = i
cell.Controls.Add(btn1)
row.Cells.Add(cell)
Next
tableContent.Rows.Add(row)
Next
End Sub
C# Code:
public void test()
{
HtmlTableRow row = new HtmlTableRow();
HtmlTableCell cell = new HtmlTableCell();
for (i = 0; i <= 10; i++) {
row = new HtmlTableRow();
for (j = 0; j <= 3; j++) {
cell = new HtmlTableCell();
cell.InnerText = "m";
LinkButton btn1 = new LinkButton();
btn1.ID = i;
cell.Controls.Add(btn1);
row.Cells.Add(cell);
}
tableContent.Rows.Add(row);
}
}
Not getting intellisence on btn1.click:
EDIT:
Answer in c# can also help me.
For VB.NET, type AddHandler btn1. and then you should see the Click event in the Intellisense, like this:
AddHandler btn1.Click, AddressOf Me.LinkButton_OnClick
Since you have dynamic content (table), you will need to rebuild the table on every page load, not just the first. The reason for this is that the Page_Load happens before the link button click event, so by the time the click event happens the table needs to have been recreated; otherwise your click event handler will try to interact with content that is not there.
Read ASP.NET Page Life Cycle Overview for more information about the page life cycle and all the events and their order.
In C# you can do:
1. Declare the handler
protected void btn1_Click(object sender, EventArgs e)
{
}
2. Assign the handler:
LinkButton btn1 = new LinkButton();
btn1.Click += new EventHandler(btn1_Click);
You have to add an event handler and an ID on the botton to be able to identify it:
public void test()
{
HtmlTableRow row = new HtmlTableRow();
HtmlTableCell cell = new HtmlTableCell();
for (i = 0; i <= 10; i++) {
row = new HtmlTableRow();
for (j = 0; j <= 3; j++) {
cell = new HtmlTableCell();
cell.InnerText = "m";
LinkButton btn1 = new LinkButton();
btn1.ID = i;
// Add EventHandler for click events
btn1.Click += new EventHandler(LinkButton_OnClick);
cell.Controls.Add(btn1);
row.Cells.Add(cell);
}
tableContent.Rows.Add(row);
}
}
Then add the following method to your code which catches the click events:
protected LinkButton_OnClick(object sender, EventArgs e)
{
var button = (LinkButton)sender;
// You can now access the id of the clicked link-button using button.ID
}
Related
I have searched for a while but can never get a clear answer on the correct way of doing this, or even if it is possible.
I am grabbing 2 rows from a table in SQL, returning them in a DataTable. I iterate through the rows and dynamically create a div for that row and then a label for each column with the stored value, and then repeats the process for the next row.
All I am missing to make it work is storing the labels into a List to bring back to the placeholder that the div will be created in.
here is a snippet... also, I want to do it this way, not with a gridview or tables for learning purposes and I already know how to use the gridview and table to do this. I have a total of 7 columns in this SQL table, and could have an unlimited number of rows.
EDIT
public void AddDiv(DataTable gameData)
{
for (int i = 0; i < gameData.Rows.Count; i++)
{
//newControl.InnerHtml = AddLabel(gameData, i);
//PlaceHolder1.Controls.Add(newControl);
HtmlGenericControl newControl = new HtmlGenericControl("div");
newControl.ID = "div" + i++;
Label lblTitle = new Label();
lblTitle.Text = gameData.Rows[i]["Game_Title"].ToString();
this.Controls.Add(lblTitle);
PlaceHolder1.Controls.Add(lblTitle);
Label lblPublisher = new Label();
lblPublisher.Text = gameData.Rows[i]["Game_Publisher"].ToString();
this.Controls.Add(lblPublisher);
PlaceHolder1.Controls.Add(lblPublisher);
Label lblGenre = new Label();
lblGenre.Text = gameData.Rows[i]["Game_Genre"].ToString();
this.Controls.Add(lblGenre);
PlaceHolder1.Controls.Add(lblGenre);
Label lblESRB = new Label();
lblESRB.Text = gameData.Rows[i]["Game_ESRB"].ToString();
this.Controls.Add(lblESRB);
PlaceHolder1.Controls.Add(lblESRB);
Label lblUserRating = new Label();
lblUserRating.Text = gameData.Rows[i]["Game_UserRating"].ToString();
this.Controls.Add(lblUserRating);
PlaceHolder1.Controls.Add(lblUserRating);
Label lblWebsite = new Label();
lblWebsite.Text = gameData.Rows[i]["Game_Website"].ToString();
this.Controls.Add(lblWebsite);
PlaceHolder1.Controls.Add(lblWebsite);
}
}
First off, the InnerHtml property of the HtmlGenericControl is a string. Your code is assigning the result of a void method to this property. I think what you want to do is create the div and pass a reference to that to the AddLabel method. Here you can create your labels and add them to the div's Control's property. Finally, add your div to the Placeholder as you currently do. Hopefully, this will get you on the right track.
protected void Page_Load(object sender, EventArgs e)
{
AddDiv();
}
public void AddDiv()
{
for (int i = 0; i < 5; i++)
{
HtmlGenericControl newControl = new HtmlGenericControl("div");
newControl.ID = "div" + i;
AddLabel(newControl, i);
PlaceHolder1.Controls.Add(newControl);
}
}
protected void AddLabel(HtmlGenericControl control, int i)
{
Label lblTitle = new Label();
lblTitle.Text = "label" + i.ToString();
control.Controls.Add(lblTitle);
Label lblPublisher = new Label();
lblPublisher.Text = "publisherLabel" + i.ToString();
control.Controls.Add(lblPublisher);
}
ASP.NET C#.
Inside UpdatePanel we have TextBox with OnTextChanged="text_changed" method and Panel.
if number 3 was typed at textbox, 3 textboxes below will appear inside Panel with different IDs.
However when button outside updatepanel clicks, dynamically created textboxes not found error occured.
How to get values of dynamically created textboxes?
Creating textbox:
protected void text_changed(Object sender, EventArgs e)
{
int n = Int32.Parse(TextBox6.Text);
Table table = new Table();
for (int i = 0; i < n; i++)
{
TableRow trow = new TableRow();
table.Rows.Add(trow);
TableCell tcell = new TableCell();
tcell.Text = (i + 1).ToString();
TextBox tb = new TextBox();
tb.ID = "TB" + i.ToString();
tcell.Controls.Add(tb);
trow.Cells.Add(tcell);
}
Panel1.Controls.Add(table);
ButtonClick //get values from created textboxes:
int n = Int32.Parse(TextBox6.Text);
for (int i = 0; i < n; i++)
{
string title = ((TextBox)UpdatePanel1.FindControl("Panel1").FindControl("TB" + i.ToString())).Text; //here null pointer exception..
}
where are you generating your textboxes? if you're creating them in text_changed event, then on the next post back your going to run into pagelife cycle issues. you'd need to cache the fact that you created them, and recreate them in the OnInit phase of the page.
i have a page where i create 2 checkboxes dynamically.
TableRow tr = new TableRow();
for (int i = 0; i < 2; i++)
{
TableCell Tc = new TableCell();
Tc.Attributes["style"] = "line-height: 30px; text-align: left";
Tc.Attributes["width"] = "50%";
Tc.Style.Add("padding-left", "5px");
//Checkboxes on left along with labels
CheckBox checkBoxCtrl = new CheckBox();
checkBoxCtrl.ID = "checkBoxCtrl" + i;
Tc.Controls.Add(checkBoxCtrl);
tr.Cells.Add(Tc);
}
once they are created in the page load event i have a Ok_button click event which requires to check if the checkbox is checked or not.
protected void Update2_Click(object sender, EventArgs e)
{
if(checkBoxCtrl.checked)
//here i wont be able to get the value
// i get the error the name checkBoxCtrl does not exist..
{
response.write("true");
}
}
but how do i do the check in this case.
thanks
Answer:
this is what needs to be done to get the checkbox values
protected void Update1_Click(object sender, EventArgs e)
{
for(int i = 0; i < ControlPropList.Count; i++)
{
CheckBox chkTest = (CheckBox)xxx.FindControl("checkBoxCtrl" + i);
{
if (chkTest.Checked)
{
Global.logger.Info("Checkbox True = " + chkTest.ID);
}
else
{
Global.logger.Info("Checkbox False = " + chkTest.ID);
}
}
}
}
This should work fine as long as you add the checkboxes to your page in the Page_PreInit method. If you add them after that (Page_Load for example), their values will not be maintained.
Read about the asp.net page lifecycle here:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
Consider storing the dynamic checkbox in a local member:
private CheckBox _myCustomCheckbox = new CheckBox();
protected override void OnInit(EventArgs e)
{
TableRow tr = new TableRow();
for (int i = 0; i < 2; i++)
{
TableCell Tc = new TableCell();
if (i == 0)
{
Tc.Attributes["style"] = "line-height: 30px; text-align: left";
Tc.Attributes["width"] = "50%";
Tc.Style.Add("padding-left", "5px");
//Checkboxes on left along with labels
_myCustomCheckbox.ID = "checkBoxCtrl" + j;
Tc.Controls.Add(_myCustomCheckbox);
tr.Cells.Add(Tc);
}
}
// the row needs added to a page control so that the child control states can be loaded
SomeTableOnThePage.Controls.Add(tr);
base.OnInit(e);
}
protected void Update2_Click(object sender, EventArgs e)
{
if(_myCustomCheckbox.Checked)
{
response.write("true");
}
}
May not be quite what you want, but I had a similar issue, I have a dynamically generated table in ASP.NET page, with dynamically generated CheckBoxes in one column. I have created the data for the table from a collection, and then as the dynamic CB's are created I give them an ID and store them in a second collection, such as an array of CB's.
So when I need to find the Checked value I simply iterate through the collection, and I can find the ones that are Checked.
Also as they were created simultaneously with the data in the dynamic table I was able to easily tie the table data row to the Checkbox value.
This obviously assumes that the dynamic table and CB's were created using some kind of looping.
This may not be the best solution but works for my current needs.
I need to dynamically create radio buttons based on dynamic list. Scenario is like I have list of files shown as Radio button in WinForm. A user clicks on radio button to select file and move forward.
I tried doing following as an example
for (int i = 0; i < 10; i++)
{
ii = new RadioButton();
ii.Text = i.ToString();
ii.Location = new Point(20, tt);
tt = tt + 20;
panel1.Controls.Add(ii);
}
The problem is how would I check which value got selected by user?
A simple way to do it is by using the RadioButtons CheckChanged event to set a variable that specifies the file that they have chosen by using the RadioButtons text or Tag property which you could set to be the file itself?
e.g.
private File f = null;
for (int i = 0; i < 10; i++)
{
ii = new RadioButton();
ii.Text = i.ToString();
ii.Location = new Point(20, tt);
ii.Tag = fileArray[i]; // Assuming you have your files in an array or similar
ii.CheckedChanged += new System.EventHandler(this.Radio_CheckedChanged);
tt = tt + 20;
panel1.Controls.Add(ii);
}
private void Radio_CheckedChanged(object sender, EventArgs e)
{
RadioButton r = (RadioButton)sender;
f = (File)r.Tag;
}
It's certainly not the most elegant way but it would work.
After posting this: Custom Header in GridView
...I have a related problem. I have added the table row during OnDataBound, and it shows up, the links are clickable. There are two problems with adding it here: first, if a postback occurs that doesn't DataBind, the row disappears; second, no events are happening when the LinkButtons are clicked. Here is the OnDataBound code:
protected override void OnDataBound(EventArgs e)
{
base.OnDataBound(e);
// Hook up the handler to create the Selection header/footer
// TODO: Wrap this in a function sometime
Table table = (Table)Controls[0];
GridViewRow row = new GridViewRow(-1, -1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
// TODO: should add css classes
TableHeaderCell cell = new TableHeaderCell();
cell.ColumnSpan = Columns.Count + 1; // plus 1 for the checkbox column
cell.HorizontalAlign = HorizontalAlign.Left; // do this or css?
HtmlGenericControl label = new HtmlGenericControl("label");
label.InnerText = "Select:";
selectNoneLK = new LinkButton();
selectNoneLK.ID = "SelectNoneLK";
selectNoneLK.Text = "None";
selectNoneLK.Click += SelectNoneLK_Click;
//selectNoneLK.CommandName = "SelectNone";
//selectNoneLK.Command += SelectNoneLK_Click;
selectAllLK = new LinkButton();
selectAllLK.ID = "SelectAllLK";
selectAllLK.Text = "All on this page";
//selectAllLK.CommandName = "SelectAll";
//selectAllLK.Command += SelectAllLK_Click;
selectAllLK.Click += SelectAllLK_Click;
cell.Controls.Add(label);
cell.Controls.Add(selectNoneLK);
cell.Controls.Add(selectAllLK);
row.Controls.Add(cell);
// Find out where to put this row
int rowIndex = 0;
if(SelectionMode == SelectionMode.AboveHeader)
{
rowIndex = 0;
}
else if(SelectionMode == SelectionMode.BelowHeader)
{
rowIndex = 1;
}
else if(SelectionMode == SelectionMode.AboveFooter)
{
rowIndex = table.Rows.Count;
}
else if(SelectionMode == SelectionMode.BelowFooter)
{
rowIndex = table.Rows.Count + 1;
}
table.Rows.AddAt(rowIndex, row);
}
You can try putting it in the RowCreated Event, while the header is being created. This might also fix your problem with the LinkButtons not working.
void GridView1_RowCreated(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.Header)
{
...your code here
}