Trying to add buttons programmatically to a webform.
Some work - others don't.
In the code below I add btnY and btnX in the Page_Load.
These both work - they show on the page and fire the event
and the code in the event handler works....
In the page load I also run bindData which gets a DataTable
and uses the data to create controls.
in the example I am only creating Button.
These buttons will appear on the page correctly but when clicked
they only do a postback ..
the code in the event handler doesn't work - does it get called?
The event handler is the same for all the buttons.
Any ideas why or how I can make it work?
protected void Page_Load(object sender, EventArgs e)
{
PlaceHolder1.Controls.Add(btn("btnY", "Y"));
Pages P = new Pages();
bindData(P.DT);
PlaceHolder1.Controls.Add(btn("btnX", "X"));
}
Button btn(string id, string text)
{
Button btn1 = new Button();
btn1.ID = id;
btn1.Text = text;
btn1.Click += new System.EventHandler(this.btn_click);
return btn1;
}
protected void bindData(DataTable dt)
{
foreach (DataRow row in dt.Rows)
{
render(Convert.ToInt32(row["PageKey"]));
}
}
protected void render(int pageKey)
{
PlaceHolder1.Controls.Add(btn("btn_" + pageKey.ToString(), "Edit"));
}
protected void btn_click(object sender, EventArgs e)
{
Button btn = (Button)sender;
string id = btn.ID;
Pages P = new Pages();
bindData(P.DT);
lt.Text = "ID=" + id;
}
Never mind .. figured it out .. example above should work, my actual code had a if (!Page.PostBack) that caused the problem
Related
My problem is that I dynamically create a table where each cell includes a linkbutton, that when clicked is supposed to remove that cell from the table.
(It is i bit more complex than that but I will not go into those details, just saying that a workaround will not do) I have read a few post on this and it usually is mentioned that the control has too be (re)made in page load or before. I have tried to run the method that runs setCellContent from both page load and page init and pre init but the _lnkBntRemoveSlotFromTable_Click method
is never called as the linkbuttons are clicked. And I am beginning to wonder there is something else wrong than just when the controls are created/recreated.
For each cell the table consist of, this is what is done:
private TableCell setCellContent(string day, DateTime timeOfDay){
TableCell newCell = new TableCell();
LinkButton lb = new LinkButton();
lb.ID = (++global_counter_id).ToString();
lb.Text = timeOfDay.ToShortTimeString();
lb.CommandArgument = timeOfDay.ToString();
lb.Command += new CommandEventHandler(_lnkBntRemoveSlotFromTable_Click);
newCell.Controls.Add(lb);
return newCell;
}
The method I want to be called:
public void _lnkBntRemoveSlotFromTable_Click(object sender, CommandEventArgs e)
{
//1. Make changes to the table
}
But the method is never called.
Finally got it working. A few changes made it work. It had ofcourse to do with when the table was created and how the id was created. For advice for others here is an example of when it works.. And make sure the ID of the dynamic control stays the same across page loads.
public partial class _default : System.Web.UI.Page
{
static int i = 0;
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
LinkButton lb = new LinkButton();
lb.ID = "id";
lb.Text = "Click me";
lb.CommandArgument = "argument";
lb.Command += new CommandEventHandler(method_to_call);
this.Panel.Controls.Add(lb);
}
private void method_to_call(object sender, CommandEventArgs e)
{
i++;
this.Label.Text = i.ToString();
}
protected void Page_Load(object sender, EventArgs e)
{
}
}
New to dynamic controls, but until now I have been creating them successfully in a
template field in my gridview, recently switched from a hyperlink to a link button
and had to make some changes but still not working
In my page I have the following code (abridged to salient parts)
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
...
...
TemplateField tf = new TemplateField();
tf.HeaderText = "Action";
tf.ItemTemplate = new AssignPage.MyTemplate(..., mylb);
GridView1.Columns.Add(tf);
protected void Page_PreInit(object sender, EventArgs e)
{
LinkButton lb = new LinkButton();
lb.Text = "AssignAll";
lb.Command += new CommandEventHandler(AssignAll_Click);
lb.CommandName = "XXX";
this.mylb = lb;
protected void AssignAll_Click(object sender, CommandEventArgs e)
{
string[] arg = new string[2]; // BREAK POINT HERE
arg = e.CommandArgument.ToString().Split(';');
...
...
Response.Redirect("BaseAndRepeats.aspx?id=" + r.Event.ID);
In the template class I have I have
LinkButton lb;
public MyTemplate(..., LinkButton _lb)
{
...
lb = _lb;
...
public void InstantiateIn(System.Web.UI.Control container)
{
...
...
// various conditional statements
lb.CommandArgument = mylist[rowCount].ReqtID.ToString() + ";" + mylist[rowCount].RotaUser;
container.Controls.Add(lb);
...
The break point in the handler is never reached
I thought I was creating the linkbutton in the right place
the linkbutton appears in the grid quite happily
when I click on the linkbutton there is a call
to Page_PreInit and to Page_Load and as I expected
it is a postback.
But AssignAll_Click is never called.
In the browser footer it shows "javascript: __dooPsotabck(..." when you hover
over the buttonlink
I believe the problem is this line:
lb.Command += new CommandEventHandler(AssignAll_Click);
Change it to:
lb.Command += AssignAll_Click;
Edit:
Also you want to move it from Page_PreInit to Page_Init but you may find more success with it in Page_Load (outside the IsPostBack). Here's an example that works for me:
On the ASPX page:
<asp:Panel ID="TestPanel" runat="server" />
Codebehind:
protected void Page_Init(object sender, EventArgs e)
{
//Init used because TestPanel doesn't exist yet
CreateTestButton();
}
private void CreateTestButton()
{
var lb = new LinkButton();
lb.Text = "hello";
lb.Command += lb_Command;
TestPanel.Controls.Add(lb);
}
void lb_Command(object sender, CommandEventArgs e)
{
throw new NotImplementedException();
}
Going over your code it looks like your adding another column into your GridView and creating a button inside that column for each row - but you've got the column being added on Page_Load and the button being created and bound to it before in Page_PreInit
I am trying to build an app, where user can select category and according to it displays its sub categories , these sub categories are buttons, which are dynamically created.
Now, as buttons are dynamically created so I am confuse how to write code under button_click event as I dont know how many subcategories are there.
So is there any way I can execute click event of a particular button , so that I can execute certain commands?
EDITED
This is the code that i tried
Button btnDynamicButton = new Button();
private void btnclick_Click(object sender, EventArgs e)
{
label2.Text = btnDynamicButton.Text;
}
private void btnappetizer_Click(object sender, EventArgs e)
{
groupBox2.Visible =false;
DataTable dt = new DataTable();
dt = itemmasterbl.SelectallrecordFromtblItem(btnappetizer.Text);
for (int i = 0; i < dt.Rows.Count; i++)
{
string name = "Appetizer" + DynamicButtonCount;
Button btnDynamicButton1 = new Button();
btnDynamicButton1.Name = name;
btnDynamicButton1.Text = name;
btnDynamicButton1.Size =
new System.Drawing.Size(150, 30);
btnDynamicButton1.Location =
new System.Drawing.Point(180, DynamicButtonCount * 30);
btnDynamicButton1.Click +=new EventHandler(btnclick_Click);<br>
Controls.Add(btnDynamicButton1);
DynamicButtonCount++;
btnDynamicButton = btnDynamicButton1;
}
}
Once I do this it creates three buttons according to number of values in itemmaster DB under appetizer, but once I click on any of the three buttons the label displays only last buttons text,because in last line I have :
btnDynamicButton = btnDynamicButton1;
Which will last buttons infos,but rather I want which ever button I press, label should display respective text. How can I achieve this.
you can put all your logic into one handler:
System.Windows.Forms.Button b = new System.Windows.Forms.Button();
b.Click += new EventHandler(b_Click);
//finally insert the button where it needs to be inserted.
...
void b_Click(object sender, EventArgs e)
{
MessageBox.Show(((System.Windows.Forms.Button)sender).Name + " clicked");
}
To your edit:
You are storing the reference for your button(s) inside the Field btnDynamicButton. Hence it always gets overwritten with the latest button you have created. You should not reference the button by using a field. The sender parameter of the click-handler contains the button element that has been clicked. See the code above: Simple cast sender to Button and you know which button has been clicked:
private void btnclick_Click(object sender, EventArgs e)
{
Button btn = (Button)sender
label2.Text = btn.Text;
}
I am doing following code to generate dynamic buttons with their click event.
protected void Button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < int.Parse(TextBox1.Text); i++)
{
Button bt = new Button();
bt.Text = "ok";
bt.Click += new EventHandler(bt_click);
this.form1.Controls.Add(bt);
}
}
protected void bt_click(object sender, EventArgs e)
{
Label1.Text = "Clicked";
}
but i am not able to generate the click event of that dynamically generated button.
Can any one help me?
For ASP.NET to be able to execute your event, control which triggered it should also exist on your page after postback. What is going on with your code looks like this:
page has several buttons you placed in design mode
you click button which generates new buttons
page loads again and looks for button you clicked, in the page
button is found, asp looks for event handler and executes it
new dynamic buttons are added and events attached, page renders again
It was all ok up till now, now problem occurs
you click button which was added dynamically
page loads again and looks for button you clicked (so it can find it's handler)
button is not found because it is not created yet. it was created dynamically to be rendered, and it wasn't created after postback at stage where asp is looking for it
General rule is that if you're adding controls dynamically and you want them to trigger events, you should do it latest in Page_Load.
For more details please read ASP.NET Page Life Cycle Overview
My previous submission was on WinForms which I have deleted. Here is the one on asp.net
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
for (int i = 0; i < int.Parse(TextBox1.Text); i++)
{
CreateButton(i);
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
}
protected void bt_click(object sender, EventArgs e)
{
Button btn = sender as Button;
Label1.Text = btn.Text + " Clicked";
}
private void CreateButton(int id)
{
Button bt = new Button();
bt.Text = "ok" + id.ToString();
bt.Click += new EventHandler(bt_click);
bt.ID = "btn" + id.ToString();
this.Form.Controls.Add(bt);
}
You need to set the position of those new buttons, or they will cover each other.
I'm not sure if its your problem, but you might want to set the location property of eachbutton you add like:
bt.Location = new Point(25,i+55);
you need to add this code in either page load or page_init event of page. then only you can access it. How to add controls dynamically asp.net
protected void Page_Load()
{
for (int i = 0; i < int.Parse(textBox1.Text); i++)
{
Button bt = new Button();
bt.Text = "ok";
bt.Click += new EventHandler(bt_click);
this.Controls.Add(bt);
}
}
I am creating one button on a page dynamically. Now I want to use the button click event on that button.
How can I do this in C# ASP.NET?
Button button = new Button();
button.Click += (s,e) => { your code; };
//button.Click += new EventHandler(button_Click);
container.Controls.Add(button);
//protected void button_Click (object sender, EventArgs e) { }
The easier one for newbies:
Button button = new Button();
button.Click += new EventHandler(button_Click);
protected void button_Click (object sender, EventArgs e)
{
Button button = sender as Button;
// identify which button was clicked and perform necessary actions
}
Simply add the eventhandler to the button when creating it.
button.Click += new EventHandler(this.button_Click);
void button_Click(object sender, System.EventArgs e)
{
//your stuff...
}
It is much easier to do:
Button button = new Button();
button.Click += delegate
{
// Your code
};
You can create button in a simple way, such as:
Button button = new Button();
button.Click += new EventHandler(button_Click);
protected void button_Click (object sender, EventArgs e)
{
Button button = sender as Button;
// identify which button was clicked and perform necessary actions
}
But event probably will not fire, because the element/elements must be recreated at every postback or you will lose the event handler.
I tried this solution that verify that ViewState is already Generated and recreate elements at every postback,
for example, imagine you create your button on an event click:
protected void Button_Click(object sender, EventArgs e)
{
if (Convert.ToString(ViewState["Generated"]) != "true")
{
CreateDynamicElements();
}
}
on postback, for example on page load, you should do this:
protected void Page_Load(object sender, EventArgs e)
{
if (Convert.ToString(ViewState["Generated"]) == "true") {
CreateDynamicElements();
}
}
In CreateDynamicElements() you can put all the elements you need, such as your button.
This worked very well for me.
public void CreateDynamicElements(){
Button button = new Button();
button.Click += new EventHandler(button_Click);
}
Let's say you have 25 objects and want one process to handle any one objects click event. You could write 25 delegates or use a loop to handle the click event.
public form1()
{
foreach (Panel pl in Container.Components)
{
pl.Click += Panel_Click;
}
}
private void Panel_Click(object sender, EventArgs e)
{
// Process the panel clicks here
int index = Panels.FindIndex(a => a == sender);
...
}