I have some questions to this post [1]: How can i create dynamic button click event on dynamic button?
The solution is not working for me, I created dynamically an Button, which is inside in an asp:table controller.
I have try to save my dynamic elements in an Session, and allocate the Session value to the object in the Page_Load, but this is not working.
Some ideas
edit:
...
Button button = new Button();
button.ID = "BtnTag";
button.Text = "Tag generieren";
button.Click += button_TagGenerieren;
tabellenZelle.Controls.Add(button);
Session["table"] = table;
}
public void button_TagGenerieren(object sender, EventArgs e)
{
TableRowCollection tabellenZeilen = qvTabelle.Rows;
for (int i = 0; i < tabellenZeilen.Count; i++)
{
...
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Session["table"] != null)
{
table = (Table) Session["table"];
Session["table"] = null;
}
}
}
It is not a good practice to store every control into Session state.
Only problem I found is you need to reload the controls with same Id, when the page is posted back to server. Otherwise, those controls will be null.
<asp:PlaceHolder runat="server" ID="PlaceHolder1" />
<asp:Label runat="server" ID="Label1"/>
protected void Page_Load(object sender, EventArgs e)
{
LoadControls();
}
private void LoadControls()
{
var button = new Button {ID = "BtnTag", Text = "Tag generieren"};
button.Click += button_Click;
PlaceHolder1.Controls.Add(button);
}
private void button_Click(object sender, EventArgs e)
{
Label1.Text = "BtnTag button is clicked";
}
Note: If you do not know the button's id (which is generated dynamically at run time), you want to save those ids in ViewState like this - https://stackoverflow.com/a/14449305/296861
The problem lies in the moment at which te button and it's event are created in the pagelifecycle. Try the page_init event for this.
Create Button in page load
Button btn = new Button();
btn.Text = "Dynamic";
btn.Click += new EventHandler(btnClick);
PlaceHolder1.Controls.Add(btn)
Button Click Event
protected void btnClick(object sender, EventArgs e)
{
// Coding to click event
}
Related
I am trying to an add event handler to an image button in one of my view of multi view control. But the event handler is not firing. But if bind the buttons in page load then the event handler is firing. Can Anyone help?
LinkButton lnkButton = new LinkButton();
lnkButton.Click += new EventHandler(CButtonClickHandlerNew);
This is how I added the event handler.
Use the following code to call the event of dynamically created button
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
placeHolder.Controls.Add(CreateButton());
}
}
public Button CreateButton()
{
Button btn = new Button();
btn.ID = "id";
btn.Text = "some text";
btn.Click += btn_Click;
return btn;
}
private void btn_Click(object sender, EventArgs e)
{
}
Whenever DropDownList SelectedIndexChanged, I am adding LinkButtons as ul-li list in codebehind. Each linkbuttons were assigned with IDs and a common Click event. Problem is code in Click event is not executed or maybe event is not triggered. My code below: [Edit] I tried like this as suggested in other posts (dynamically created list of link buttons, link buttons not posting back)
protected void ddl_SelectedIndexChanged(object sender, EventArgs e)
{
populate();
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
populate();
}
void populate()
{
HtmlGenericControl ulList = new HtmlGenericControl("ul");
panel.Controls.Add(ulList);
foreach (DataRow dr in drc)
{
HtmlGenericControl liList = new HtmlGenericControl("li");
ulList.Controls.Add(liList);
var lnk = new LinkButton();
lnk.ID = dr["col1"].ToString();
lnk.Text = dr["col1"].ToString();
lnk.Click += Clicked;
liList.Controls.Add(lnk);
}
}
private void Clicked(object sender, EventArgs e)
{
var btn = (LinkButton)sender;
label1.Text = btn.ID.ToString();
}
Im missing something. Any help please.
Here the issue is with the ViewState. When the selected index of the dropdownlist changes there is a postback which takes place and the previous state is lost, so at this point you have to maintain the state of the controls.
Now in your code actually the state of the control is lost and so the click event does not fire. So the solution is to maintain the state of the controls.
The Below is a working example, you can just paste it and try.
This is my page load.
protected void Page_Load(object sender, EventArgs e)
{
for (var i = 0; i < LinkButtonNumber; i++)
AddLinkButton(i);
}
Similarly you have to maintain the state of the previously added control like this.
private int LinkButtonNumber
{
get
{
var number = ViewState["linkButtonNumber"];
return (number == null) ? 0 : (int)number;
}
set
{
ViewState["linkButtonNumber"] = value;
}
}
The below is my SelectedIndexChanged Event for the DropDownList
protected void Example_SelectedIndexChanged(object sender, EventArgs e)
{
AddLinkButton(LinkButtonNumber);
LinkButtonNumber++;
}
I have a function which dynamically creates the controls, which is called on the page load and on SelectedIndexChanged.
private void AddLinkButton(int index)
{
LinkButton linkbutton = new LinkButton { ID = string.Concat("txtDomain", index) };
linkbutton.ClientIDMode = ClientIDMode.Static;
linkbutton.Text = "Link Button ";
linkbutton.Click += linkbutton_Click;
PanelDomain.Controls.Add(linkbutton);
PanelDomain.Controls.Add(new LiteralControl("<br />"));
}
And this is the Click event for the LinkButton
void linkbutton_Click(object sender, EventArgs e)
{
//You logic here
}
I solved it using brute code lol.
Since controls' event were not bound on postback then we recreate them on postback. So in my Page_Load I called the module that re-creates the controls, thus binding them to corresponding event. This works, but...
Re-creating these controls create duplicates (Multiple Controls with same ID were found) and you will get into trouble in instances of finding a control by ID like using panel.FindControl.
To remedy this scenario, I put a check if same control ID already existed before recreating them, and voila! It works.
protected void Page_Load(object sender, EventArgs e)
{
populate();
}
void populate()
{
HtmlGenericControl ulList = new HtmlGenericControl("ul");
panel.Controls.Add(ulList);
foreach (DataRow dr in drc)
{
HtmlGenericControl liList = new HtmlGenericControl("li");
ulList.Controls.Add(liList);
if (liList.FindControl(dr["col1"].ToString()) == null)
{
var lnk = new LinkButton();
lnk.ID = dr["col1"].ToString();
lnk.Text = dr["col1"].ToString();
lnk.Click += Clicked;
liList.Controls.Add(lnk);
}
}
}
I'm currently working on a website using c# and asp.net. For this purpose, I need to create dynamic controls but I enconter some issues. I already read official documentation and searched for lots of tutorial but unfortunately, no one allowed me to fix this problem.
Here is a very simplified example of what I'm trying to do;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
CreateControls();
else
UpdatePage();
}
protected void CreateControls()
{
Button button1 = new Button();
button1.ID = "_Button1";
button1.Text = "Button1";
button1.Click += new System.EventHandler(_ClickEvent);
_Panel.Controls.Add(button1);
Button button2 = new Button();
button2.ID = "_Button2";
button2.Text = "Button2";
button2.Click += new System.EventHandler(_ClickEvent);
_Panel.Controls.Add(button2);
}
protected void UpdatePage()
{
Button button1 = ((Button)_Panel.FindControl("_Button1"));
button1.Text = "I went through UpdatePage and changed";
Button button2 = ((Button)_Panel.FindControl("_Button2"));
button1.Text = "I went through UpdatePage and changed";
}
protected void _ClickEvent(object sender, EventArgs e)
{
}
The aim here would just be to change the buttons' text when clicking on one of them. "Page_Load" method is correctly called as well as the "UpdatePage" one, but in the latter, Button1 and Button2 controls have disappeared (they are not in the panel controls anymore) and an NullPointer exception is obviously raised.
Would anybody have an explanation ? I know I probably missed something about page life cycle but could not find any clear solution anywhere.
Thanks a lot !
You are creating the controls the first time the page is loaded, but the Page_Load event is too late to add controls to the page and have WebForms know about that.
On the initial page load, somewhere between the OnInit and Page_Load, WebForms makes a note of what controls are currently on the page and sets them up in the view state and all of that stuff, so that they next time you post back it knows those controls should be there. If you don't add your controls until Page_Load, WebForms isn't really paying attention any more to what you're adding to the page, so they next time you post back it doesn't know to put those controls on the page.
Move your CreateControls call into the OnInit method. This will tell WebForms at the appropriate time to create the controls (about the same time that any controls from the .aspx markup get added, although slightly later). Then WebForms will be aware of those controls and will apply any view state necessary (if it's a postback), and then finally on Page_Load you can muck with the control data with your UpdatePage call.
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
CreateControls();
}
Think of OnInit as "put all of the controls on the page and wire up event handlers".
Think of Page_Load as "put data into the controls that are already there".
The controls that you are creating dynamically will be lost on postback. Try this:
protected void Page_Load(object sender, EventArgs e)
{
CreateControls();
UpdatePage();
}
protected void CreateControls()
{
Button button1 = new Button();
button1.ID = "_Button1";
button1.Text = "Button1";
button1.Click += new System.EventHandler(_ClickEvent);
_Panel.Controls.Add(button1);
Button button2 = new Button();
button2.ID = "_Button2";
button2.Text = "Button2";
button2.Click += new System.EventHandler(_ClickEvent);
_Panel.Controls.Add(button2);
}
protected void UpdatePage()
{
Button button1 = ((Button)_Panel.FindControl("_Button1"));
button1.Text = "I went through UpdatePage and changed";
Button button2 = ((Button)_Panel.FindControl("_Button2"));
button1.Text = "I went through UpdatePage and changed";
}
protected void _ClickEvent(object sender, EventArgs e)
{
}
Will try it:
protected String TextButton1
{
get { return (String) ViewState["TextButton1"]; }
set { ViewState["TextButton1"] = value; }
}
protected String TextButton2
{
get { return (String)ViewState["TextButton2"]; }
set { ViewState["TextButton2"] = value; }
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
CreateControls();
}
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
UpdatePage();
}
}
protected void CreateControls()
{
Button button1 = new Button();
button1.ID = "_Button1";
button1.Text = String.IsNullOrEmpty(TextButton1) ? "The First Value" : TextButton1;
button1.Click += new System.EventHandler(_ClickEvent1);
_Panel.Controls.Add(button1);
Button button2 = new Button();
button2.ID = "_Button2";
button2.Text = String.IsNullOrEmpty(TextButton2) ? "The First Value" : TextButton2;
button2.Click += new System.EventHandler(_ClickEvent2);
_Panel.Controls.Add(button2);
}
protected void UpdatePage()
{
Button button1 = ((Button)_Panel.FindControl("_Button1"));
button1.Text = String.IsNullOrEmpty(TextButton1) ? "The First Value" : TextButton1;
Button button2 = ((Button)_Panel.FindControl("_Button2"));
button2.Text = String.IsNullOrEmpty(TextButton2) ? "The First Value" : TextButton2;
}
protected void _ClickEvent1(object sender, EventArgs e)
{
TextButton1 = "test";
Button b = (Button) sender ;
b.Text = TextButton1;
}
protected void _ClickEvent2(object sender, EventArgs e)
{
TextButton2 = "test";
Button b = (Button)sender;
b.Text = TextButton2;
}
I was create a button dynamically with event handler. But the event not fired. Please help me to do this. My partial code is here.
Button btn = new Button();
btn.ID = "btn" + i;
btn.Text = "Add New";
Panel1.Controls.Add(btn);
btn.Click += new EventHandler(this.GreetingBtn_Click);
Panel1.Controls.Add(new LiteralControl("<br /><br />"));
void GreetingBtn_Click(Object sender, EventArgs e)
{
create();
}
I want to access the create() function when i click the button.
Without knowing much about your code, I'm guessing you're not creating the control in the appopriate stage of the page life cycle of ASP.NET
what you need is PreInit, as described here:
Raised after the start stage is complete and before the initialization stage begins.
Use this event for the following:
Create or re-create dynamic controls.
if you are adding this dynamic button on page load, make sure its under
if (!IsPostBack)
{
//add button here
}
always make your code of creating one time control that will made should be in side !ispostback because they are not need to be created again and again
if (!IsPostBack)
{
//Your code should be their enter code here
}
List<string> myControls = new List<string>();
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
myControls = new List<string>();
ViewState["myControls"] = myControls;
}
}
protected void override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
myControls = (List<string>)ViewState["myControls"];
foreach(string controlID in myControls){
//method to create your buttons goes here.
createButtons(controlID);
}
}
public void createButtons(string btnID){
Button btn = new Button();
btn.ID = btnID;
btn.Text = "Add New";
btn.Click += new RoutedEventHandler(this.GreetingBtn_Click);
Panel1.Controls.Add(btn);
Panel1.Controls.Add(new LiteralControl("<br /><br />"));
}
void GreetingBtn_Click(Object sender, RoutedEventArgs e){
create();
}
Give this code a try. When adding controls dynamically in asp.net you have to recreate the controls in the postback. The easiest way to do this is using the viewstate as I showed above.
Common signs of not doing this correctly are: control disappears when you click it or event just doesn't fire at all. Hope this helps someone!
Move btn.Click += new EventHandler(this.GreetingBtn_Click); line one level up i.e. before adding to parent And try Routed events.
Button btn = new Button();
btn.ID = "btn" + i;
btn.Text = "Add New";
btn.Click += new RoutedEventHandler(this.GreetingBtn_Click);
Panel1.Controls.Add(btn);
Panel1.Controls.Add(new LiteralControl("<br /><br />"));
void GreetingBtn_Click(Object sender, RoutedEventArgs e)
{
create();
}
Clicking on any of the dynamically generated button controls does indeed call the b_Click method and delete the given user, however, upon deleting the page does not reload the 'new' list of users.
protected void Page_Load(object sender, EventArgs e)
{
DbDB db = new DbDB();
List<User> users = db.GetUsers().ExecuteTypedList<User>();
foreach (User u in users)
{
Button b = new Button();
b.Text = u.FirstName;
b.Click += new EventHandler(b_Click);
PlaceHolder1.Controls.Add(b);
}
}
}
void b_Click(object sender, EventArgs e)
{
Button b = (Button)sender;
DbDB.User.Delete(x => x.FirstName == b.Text);
}
protected void Page_Load(object sender, EventArgs e) {
LoadUsers();
}
void b_Click(object sender, EventArgs e) {
Button button = (Button)sender;
string firstName = button.CommandArgument;
DbDB.User.Delete(x => x.FirstName == firstName);
PlaceHolder1.Controls.Remove(button);
}
void LoadUsers() {
DbDB db = new DbDB();
List<User> users = db.GetUsers().ExecuteTypedList<User>();
foreach (User user in Users) {
Button button = new Button();
button.CommandArgument = user.FirstName; // normally the user "id" to identify the user.
button.Text = user.FirstName;
button.Click += new EventHandler(b_Click);
PlaceHolder1.Controls.Add(button);
}
}
That's because the Page_Load event is called before the Click event so when you're retrieving the list of users from the database in Page_Load the user is still in there. As a quick solution you could move the code from Page_Load to PreRender event.
Have a look at this link for more info on the page life cycle: http://msdn.microsoft.com/en-us/library/ms178472.aspx
You don't need to select users with every post-back. Also you don't need to create controls at runtime for this.
Following is an alternative way.
<asp:Repeater runat="server" ID="myRepeater">
<ItemTemplate>
<asp:Button runat="server" OnClick="Button_Click" Text='<%# DataBinder.Eval(Container.DataItem, "FirstName") %>' />
</ItemTemplate>
</asp:Repeater>
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
// load users
myRepeater.DataSource = users;
myRepeater.DataBind();
}
}
protected void Button_Click(object sender, EventArgs e)
{
// delete user
Button button = sender as Button;
button.Visible = false;
}
Write your page_load body inside
if(!IsPostBack)
{
....
}
That should work.