Can you help me understand why, when the page is first loaded by the example below, the buttons don't work as intended eg Button 2 doesn't call GetItems(int.Parse("2"), 3); but rather calls GetItems(int.Parse("4"), 3); however after the first postback all the buttons work correctly e.g. Buttonx calls GetItems(int.Parse("x"), 3);
Thanks
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
GetItems(1, 2); //default values (first time the page is loaded)
}
GenerateButtons(5);
}
private void GenerateButtons(int c)
{
LinkButton[] x = new LinkButton[c];
for(int i=0; i<c;i++)
{
x[i] = new LinkButton();
x[i].Text = (i+1).ToString();
Panel1.Controls.Add(x[i]);
x[i].OnClick += new EventHandler(Button_Click);
}
}
protected void Button_Click(object sender, EventArgs e)
{
Button button = (Button)sender; // Which button was clicked;
GetItems(int.Parse(button.Text), 3); //3 is a constant; first argument is index of button extracted from its caption
}
PS. when I refer to button 1 I have button[0] in mind. button2=button[1] and so on. after postback button1 is correctly attached to the event to trigger GetItems(1,3). Before the postback button1 causes GetItems(3,3) to run. Not as intended
Use the Page_Init so it will work on the first load
protected void Page_Init(object sender, EventArgs e)
{
GenerateButtons(5);
}
Source: https://msdn.microsoft.com/en-us/library/ms178472.aspx
Init Raised after all controls have been initialized and any skin
settings have been applied. The Init event of individual controls
occurs before the Init event of the page. Use this event to read or
initialize control properties
.
When you dynamically create controls you do so in Page_PreInit not Page_Load
protected void Page_PreInit(object sender, EventArgs e)
{
GenerateButtons(5);
}
This article explains and will help you
http://www.robertsindall.co.uk/blog/dynamically-adding-web-controls/
Related
There is an issue that I've been struggling with it which is I generate a button in page load event and I assign a new handler for it but the event is not executed.
I cannot spot the problem.
If there are better ways to do this assignment please inform me about it.
Here is my C# code:
protected void Page_Load(object sender, EventArgs e)
{
Button edit = new Button();
edit.Text = "edit";
edit.ID = "editbtn";
edit.Click += new EventHandler(this.edit_Click);
info.Controls.Add(edit);
}
protected void edit_Click(object sender, EventArgs e)
{
Response.Redirect("Registration.aspx");
}
And info is an existing asp panel on my page.
I have a button created in code behind like so:
some method {
Button btnExportToExcel = new Button();
btnExportToExcel.Text = "Export To Excel";
btnExportToExcel.Click += new EventHandler(btnExportToExcel_Click);
pnlListView.Controls.Add(btnExportToExcel);
}
protected void btnExportToExcel_Click(object sender, EventArgs e)
{
//do something
}
The problem is that I can't ever get to execute the code from the event method.
Why is that?
are you adding controls to page in preinit event handler? Check
You must add the button to any controler .
protected void Page_Load(object sender, EventArgs e)
{
Button btnExportToExcel = new Button();
btnExportToExcel.Text = "Export To Excel";
btnExportToExcel.Click += new EventHandler(btnExportToExcel_Click);
//this is add the button to the form1
this.form1.Controls.Add(btnExportToExcel);
}
void btnExportToExcel_Click(object sender, EventArgs e)
{
//...
Response.Write("click me...");
}
Please add the dynamic controls in the Page's Init event handler so that the ViewState and Events are triggered appropriately.
I want to create a method in code behind that creates a button and places it in a PlaceHolder. I want this button to have a Click event.
After calling the "test" method button is placed correctly but the click event is not called.
private void test()
{
Button linkBtn1 = new Button();
linkBtn1.Text = "linkBtn1";
linkBtn1.OnClientClick = "return false;";
linkBtn1.Click += new EventHandler(linkBtn1_Click);
PagesPlaceHolder.Controls.Add(linkBtn1);
}
void linkBtn1_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
}
Removing the OnClientClick = "return false;" is necessary but not sufficient to get this to work. If you want the event handler on the dynamically added button to be triggered, you'll need to add this button every time the page loads.
One simple way would be to save the fact that the button has been added in ViewState, and then check that on PageLoad, and re-add the button if needed.
Here's a sample that works for me (and throws the exception when clicked)
protected void Page_Load(object sender, EventArgs e)
{
//if the button was added previously, add it again
if (ViewState["Added"] != null && (bool)ViewState["Added"])
addButton();
}
//this is the method that adds the button
protected void add_Click(object sender, EventArgs e) {
ViewState["Added"] = true;
addButton();
}
private void addButton() {
Button linkBtn1 = new Button();
linkBtn1.Text = "linkBtn1";
linkBtn1.Click += new EventHandler(linkBtn1_Click);
placeholder1.Controls.Add(linkBtn1);
}
void linkBtn1_Click(object sender, EventArgs e) {
throw new Exception("Button Click Event Triggered. Hello yellow screen!!!");
}
As #oleksii points out, have the clientside code is returning false so the form never gets submitted. You need to comment this out, then your event handler should fire.
Suppose there is a user control in a page called Paging.ascx that is embedded in PageWithResults.aspx. This control has the necessary properties to keep track of various details about what page you're on (ie: CurrentPage, TotalRecordsInResults, RecordsPerPage, etc..). It also contains events that fire off when you click on a hyperlink ("next page" or "previous page"). Example below. I need to tell PageWithResults.aspx that one of these LinkButton web controls was clicked. I think I need to assign a delegate in the page, so that when this user control event is called (hyperlink is clicked), it also calls some other method/event in the page class. That way I can quickly check what the new value of CurrentPage is (based on what was called in the event below) and get a new result set for the new page (based on the CurrentPage property). But I'm not sure of the best approach. I'm thinking this will require a delegate, but I'm not sure how to wire it up. If you need more details, please ask.
protected void btnNext_Click(object sender, EventArgs e)
{
this.CurrentPage = this.CurrentPage + 1;
if (OnPageChanged != null) OnPageChanged(this.CurrentPage);
}
I'm thinking I have to put my delegate here somewhere. ??
protected void btnNext_Click(object sender, EventArgs e)
{
this.CurrentPage = this.CurrentPage + 1;
if (OnPageChanged != null) OnPageChanged(this.CurrentPage);
//delegate to call object.method or something
}
Using an event would work fine.
You would create the event within your UserControl like so:
public event EventHandler ButtonClicked;
Then invoke the event when required:
protected void Button1_Click(object sender, EventArgs e)
{
if (ButtonClicked != null)
ButtonClicked(this, new EventArgs());
}
In your page you would need to assign an event handler:
protected void Page_Load(object sender, EventArgs e)
{
UserControl1.ButtonClicked += new EventHandler(UserControl1_ButtonClicked);
}
void UserControl1_ButtonClicked(object sender, EventArgs e)
{
}
As well as using the above approach you can also cast the Page reference in the UserControl and call a public method directly:
MyPage page = (MyPage)Page;
page.AMethod();
Hope this helps.
I'm making dynamic table at Page_LoadComplete, I cant do in at Page_Load becouse data can be changed during events process, so at Page_LoadComplete i make some buttons and want add them EventHandler:
protected void Page_LoadComplete(object sender, EventArgs e) {
btn.Click += new EventHandler(b_Click);
}
But it doesnt work, how to add events to button not at Page_Load?
simple, even not dynamic code:
void b_Click(object sender, EventArgs e) {
Label1.Text = "!!!";
}
protected void Page_Load(object sender, EventArgs e) {
Button1.Click += new EventHandler(b_Click);
}
on Page_Load works fine.
protected void Page_LoadComplete(object sender, EventArgs e) {
Button1.Click += new EventHandler(b_Click);
}
on Page_LoadComplete do nothing.
Ok here's the example:
Given this html snippet:
<body>
<form id="form1" runat="server">
<div>
<asp:Button runat="server" Text="Click Me" OnClick="go_" />
</div>
</form>
</body>
public partial class WebForm1 : System.Web.UI.Page
{
public int ControlCount
{
get { return ViewState["Controls"] == null ? 0 : (int)ViewState["Controls"]; }
set { ViewState.Add("Controls", value); }
}
protected void Page_Load(object sender, EventArgs e)
{
for(int i = 0; i < ControlCount; i++)
{
Button b = new Button();
b.Click += btn_Click;
b.Text = "Hi";
form1.Controls.Add(b);
}
}
void btn_Click(object sender, EventArgs e)
{
((Button)sender).Text = "bye";
}
protected void go_(object sender, EventArgs e)
{
Button btn = new Button();
btn.Text = "Hi";
form1.Controls.Add(btn);
btn.Click += new EventHandler(btn_Click);
ControlCount++;
}
}
Every time you click the first button a new button will be added to the page with the text "Hi", and every time you click a "Hi" button the text for THAT button only will change to "Bye"
This works because I add the controls twice. Once in the event handler of the main button, where I determine that I need a new control, and then AGAIN in OnLoad where I have a new, empty page again, but now I know (via ControlCount) how many controls I added.
The problem is the control doesn't exist on postback (since you created it at run time). Creating the control in Init should solve this, and will allow the event to fire. You can change all of the properties in LoadComplete if you like, but the button needs to exist at that point.
What you're trying will never work because controls that are added dynamically must be REadded every time the page reloads.
Since your control population is based on the data being used in the form, you should put all your control creation logic in a single function, and in your event handlers, maniuplate the data then call your control creation logic function, while in Page Load you would JUST call the control creation function (presuming that you've already persisted the data between calls) so that all the controls that were created the first go around get recreated. Then, once they have been recreated, they can respond to the events that they fired.