I've got a page in ASP.NET, and I'm dynamically adding a subclass of WebControls.Button to the Controls data member of a pre-existing static TableCell. The button displays fine in the browser as expected. But when I click the button, the event handler I added for button.Click is not being called. Any suggestions as to why this is?
var controls = this.displaytable.Rows[i].Cells[j].Controls;
var button = new TableButton(j, i);
button.Click += new EventHandler(this.button_Click);
button.UseSubmitBehavior = false;
button.Text = "Available";
controls.Add(button);
Dynamically added buttons must be created on every request, most likely it is sufficient before raising postback events (e.g. OnLoad). Button needs to have an explicit ID sometime:
var controls = this.displaytable.Rows[i].Cells[j].Controls;
var button = new TableButton(j, i);
button.Click += new EventHandler(this.button_Click);
button.UseSubmitBehavior = false;
button.Text = "Available";
button.Id = string.Format("TableButton_{0}_{1}", j, i);
controls.Add(button);
This SO answer may help little bit: ASP.NET dynamic Command Button event not firing.
Related
In my application I dynamically create buttons and add them to a flow control that is later cleared. I have this on a timer to refresh every X seconds to clear then add buttons. This is all being done on the main form.
The problem is when I have a child form launched the main form will steal focus every time the controls are added to the flow control.
Here is the code I have that dynamically clears and adds the controls on the main form.
I call this before adding the controls
flw_users.Controls.Clear();
This is what I call to dynamically create/add the buttons to the flow control.
private void DisplayNewMobileUser(string MobileUserName)
{
// Set Button properties
Button button = new Button();
button.Text = MobileUserName;
button.Size = new System.Drawing.Size(171, 28);
button.Name = MobileUserName;
button.BackColor = System.Drawing.Color.White;
button.FlatAppearance.BorderColor = System.Drawing.Color.White;
button.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Bold);
button.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
button.ForeColor = System.Drawing.Color.Black;
button.Margin = new System.Windows.Forms.Padding(0, 1, 0, 1);
button.TextAlign = System.Drawing.ContentAlignment.TopLeft;
button.Click += new EventHandler(MobileUserName_OnClick);
flw_users.Controls.Add(button);
}
Is there a way to add buttons to a flow control with out it always stealing focus ?
Thanks to LarsTech I researched how to properly dispose each control added to flw_users. The main issues was fixed by changing the OnClick event to change focus to a label, which in turn didn't cause the main form to gain topmost every time the controls were cleared and re added. So everytime I clicked a button that button still had focus while the new form appeared.
Thanks everyone !
Here is the code I used to properly clear the controls
private void ClearUsers()
{
List<Control> ctrls = new List<Control>();
foreach (Control c in flw_users.Controls)
{
ctrls.Add(c);
}
flw_users.Controls.Clear();
foreach (Control c in ctrls)
{
c.Dispose();
}
}
So I found this very puzzling problem which involves dynamic buttons.
Here is my method that creates the buttons:
private void CreateButtons()
{
//Button outside loop works
Button selectItem = new Button();
selectItem.Text = "Hello World";
selectItem.ID = "btn";
selectItem.Click += selectItem_Click;
PlaceHolder1.Controls.Add(selectItem);
int ItemCounter = 0;
for (int i = 0; i < BillDate.Count; i++)
{ //Button inside loop doesnt work
ItemCounter++;
Button selectItem = new Button();
selectItem.Text = "Hello World";
selectItem.ID = "btn-" + ItemCounter.ToString();
selectItem.Click += selectItem_Click;
PlaceHolder1.Controls.Add(selectItem);
}
}
Now here is the problem,
the button that is created outside the loop works fine (event handler selectItem_Click only redirects page).
Why does the button not work inside the loop and why does it work outside the loop?
All of the buttons in your loop have the same ID, since you're not incrementing ItemCounter. While you could just use i instead, you don't appear to be using the ID at all, so you're better off just not setting it in the first place.
Also keep in mind that on the post back the buttons need to be created and added to the page in the PreInit event in order for the event handler to be able to run.
Dynamically creating controls, particularly controls that have handlers on subsequent postbacks, can be quite tricky. It's not uncommon at all to need data from the request to be able to generate the controls, but to need the controls to be generated before the request is processed by ASP for the events to fire. It's dramatically easier to create a template that you bind your data to, using something like a GridView or a Repeater instead, as it will be able to properly handle re-creating the controls before the request is processed while still allowing you to have a dynamic number of instances of the template.
**Use the below code it will work.**
private void CreateButtons()
{
//Button outside loop works
Button selectItem = new Button();
selectItem.Text = "Hello World";
selectItem.ID = "btn";
selectItem.Click += selectItem_Click;
PlaceHolder1.Controls.Add(selectItem);
int ItemCounter = 0;
for (int i = 0; i < BillDate.Count; i++)
{ //Button inside loop doesnt work
Button selectItem = new Button();
selectItem.Text = "Hello World";
selectItem.ID = "btn-" + ItemCounter.ToString();
selectItem.Click += selectItem_Click;
ItemCounter++;
PlaceHolder1.Controls.Add(selectItem);
}
}
I'm trying to close a dynamically created form with a dynamic button (this is the simplest of my jobs, I am also adding other buttons to do other jobs but I figured this is a good place to start).
As of now I can create the form, button and the click event for that button, but I don't know what to add within the click event function to close the host of that button. I am guessing I can somehow access the buttons parent through the click function? Or maybe pass the form control as an argument in the function? Any help is appreciated!
//Create form
Snapshot snapshot = new Snapshot();
snapshot.StartPosition = FormStartPosition.CenterParent;
//Create save button
Button saveButton = new Button();
saveButton.Text = "Save Screenshot";
saveButton.Location = new Point(snapshot.Width - 100, snapshot.Height - 130);
saveButton.Click += new EventHandler(saveButton_buttonClick);
//Create exit button
Button exitButton = new Button();
exitButton.Text = "Exit";
exitButton.Location = new Point(snapshot.Width - 100, snapshot.Height - 100);
//Add all the controls and open the form
snapshot.Controls.Add(saveButton);
snapshot.Controls.Add(exitButton);
snapshot.ShowDialog();
And my click event function looks pretty much normal:
void saveButton_buttonClick(object sender, EventArgs e)
{
}
Unfortunately I don't know what to add for the function to work! Thanks in advance for any help someone can give me! I feel like this should be a straight-forward problem to solve but I haven't been able to figure it out...
While it's certainly possible to do this with a named function, it's generally simpler to just use an anonymous function in cases like this:
Snapshot snapshot = new Snapshot();
snapshot.StartPosition = FormStartPosition.CenterParent;
//Create save button
Button saveButton = new Button();
saveButton.Text = "Save Screenshot";
saveButton.Location = new Point(snapshot.Width - 100, snapshot.Height - 130);
saveButton.Click += (_,args)=>
{
SaveSnapshot();
};
//Create exit button
Button exitButton = new Button();
exitButton.Text = "Exit";
exitButton.Location = new Point(snapshot.Width - 100, snapshot.Height - 100);
exitButton.Click += (_,args)=>
{
snapshot.Close();
};
//Add all the controls and open the form
snapshot.Controls.Add(saveButton);
snapshot.Controls.Add(exitButton);
snapshot.ShowDialog();
A simple way is to use a lambda method:
Button exitButton = new Button();
exitButton.Text = "Exit";
exitButton.Click += (s, e) => { shapshot.Close(); };
I tried to call click event but it does not call it
I tried this codes: like
objImage.Click += new ImageClickEventHandler(WebForm4.ImageButtons_Click);
objImage.Click += WebForm4.ImageButtons_Click;
my codes :
public HtmlGenericControl CreateDIV_OyVerme_Sub_Yildiz(string id, int subId)
{
HtmlGenericControl objDiv = new HtmlGenericControl("div");
objDiv.ID = strControlName_DivYildiz + id + "_" + subId;
objDiv.Attributes.Add("class", strClassName_DivYildiz);
//objDiv.Attributes.Add("runat", "server");
ImageButton objImage = new ImageButton();
objImage.Attributes.Add("runat", "server");
objImage.CommandArgument = id;
//objImage.Src = strImgSrc_yildiz;
objImage.Click += new ImageClickEventHandler(WebForm4.ImageButtons_Click);
//objImage.Click += WebForm4.ImageButtons_Click;
objImage.Attributes.Add("onclick", "WebForm4.ImageButtons_Click();");
objImage.ID = strControlName_ImageYildiz + id +"_" + subId;
objImage.ImageUrl = strImgSrc_yildiz;
objImage.OnClientClick = strOnClientClickFunc_yildiz;
// objImage.Attributes.Add("OnClick","WebForm4.amethod (o;");
objImage.Style.Add(HtmlTextWriterStyle.Height, "19px");
objImage.Style.Add(HtmlTextWriterStyle.Width, "20px");
objImage.Style.Add(HtmlTextWriterStyle.BorderWidth, "0px");
objImage.Style.Add(HtmlTextWriterStyle.Position, "relative");
objImage.Style.Add(HtmlTextWriterStyle.Top, "13px");
objImage.Style.Add(HtmlTextWriterStyle.Left, "6px");
objImage.Style.Add("float", "left");
objImage.ToolTip = subId + "/" + 5;
// calling the method
// objImage.Attributes.Add("OnClientClick", "return(GetRssID(objRssItem));");
// var duck = objRssItem;
// objImage.Click += (s, e) => { WebForm4.amethod(objRssItem); };
//objImage.Click += WebForm4.amethod (objRssItem);
objDiv.Controls.Add(objImage);
return objDiv;
}
You don't need to add the attribute: onclick.
remove this line:
objImage.Attributes.Add("onclick", "WebForm4.ImageButtons_Click();");
you can simply do it like this:
ImageButton img = new ImageButton();
img.Click+=new ImageClickEventHandler(img_Click);
img.ID = "img";
img.Attributes.Add("runat","server");
form1.Controls.Add(img);
There is no issue in registering the event handler - either of below lines would register the event handler:
objImage.Click += new ImageClickEventHandler(WebForm4.ImageButtons_Click);
objImage.Click += WebForm4.ImageButtons_Click;
It's a dynamically generated image button, so for event handler to work, you need to ensure that
The image button must be re-created and added to control hierarchy on the subsequent post-back. If control is not present on post-back then it cannot raise the event.
You must ensure that the control has same ID on the post-back. Not only that it must be in the same control hierarchy and its parents also need to have same ids. The essential point is that control gets located using its ID.
The control (image button) must get added to the page's control hierarchy as early as possible - Page_Init would be the best but if that's not possible then page_load may work. Creating the control in any subsequent event would not trigger the post-back event.
Here is a quick code snippet, that doesn't seem to work at all for me. I'm reading from a file to create a list of radio buttons. The problem is that when one of the radio buttons is clicked the Event Handler I have set up in the code doesn't fire. I have tested it over and over in debug mode with line breaks... all with no luck. Am I missing something obvious here????
strLine = strLine.Trim();
System.Diagnostics.Debug.WriteLine("[3-a] ship by date - date: " + strLine);
try{ shipByDate = (Convert.ToDateTime(strLine)); }
catch (Exception e) { shipByDate = new DateTime(); }
shipByDesc = sr.ReadLine().Trim();
System.Diagnostics.Debug.WriteLine("[3-b] ship by date - desc: " + shipByDesc);
RadioButton button = new RadioButton();
button.Text = shipByDesc + " - " + shipByDate.ToString("MM/dd/yyyy");
button.Checked = false;
button.GroupName = "shipByOptions";
button.ID = "shipByRadio" + count;
//button.EnableViewState = true;
button.AutoPostBack = true;
button.CheckedChanged += new EventHandler(shipBy_CheckedChanged); // <-- doesn't work!!!
//form1.Controls.Add(button);
shipByPlaceHolder.Controls.Add(button);
You need to add the button on every postback before events attached to it will fire.
If you think about it for a moment, it will make sense - if the button has not been created (on the postback), then there are no button events that can fire. The button must exist before events attached to it can be fired.
The OnInit page event is the most suitable place to add dynamic controls to a page.
Read about the asp.net page life cycle.