I'm creating a table containing a couple of buttons. These buttons hookup to events firing a method for updating a specific database item. For somekind of reason the event isn't proper hooked-up. The method that should be executed isn't executed at all. What am I doing wrong
pseudo code:
public void createTable(List<BLL> itemlist)
{
//newtable;
foreach (BLL item in itemlist)
{
//newrow;
//create multiple cells...
TableCell cell = new TableCell();
Button button = new Button();
button.ID = "buttonname" + counter.ToString();
button.Text = "Update";
button.Click += new System.EventHandler(this.UpdateButton_Click);
cell.Controls.Add(button);
//addCellToTableRow
}
//addRowToTable
}
public void UpdateButton_Click(object sender, EventArgs e)
{
//logic to get sender and update database.
//debugger doesn't get to the breakpoint here.
}
You need to read up on the ASP.NET page life cycle.
When you create dynamic controls, you need to recreate them on every post back as well - this is best done in the OnInit event handler.
If you do not do so, the objects and any attached events do not exist, so events will not fire on them.
Related
The problem we are having is accessing the click event for a button which is created in the click event of another button i.e. clicking the first button generates a new panel and controls, and we now want the button on this newly created panel to perform an action.
The controls have been declared at the top of the class as follows:
Panel createElementPage = null;
TextBox elementDescription = null;
TextBox elementName = null;
Button continueButton = null;
AuditSystem audit;
Here is an excerpt of the method that generates the new panel, the part that defines the continueButton is written as follows:
public void CE_Click(object sender, EventArgs e)
{
createElementPage.Controls.Add(elementDescription);
continueButton = new Button();
continueButton.Text = "Continue";
continueButton.Location = new Point(700, 500);
continueButton.Size = new Size(100, 50);
createElementPage.Controls.Add(continueButton);
}
We want to access the continueButton's click event handler but the method we have written does not seem to be working. This is what we have so far:
private void continueButton_Click(object sender, EventArgs e)
{
Console.WriteLine(" something");
}
Clicking the button yields no results, and we have tried a few solutions such as implementing a seperate eventHandler method. Does anybody have a fix for this?
You have to actually subscribe to the event:
continueButton.Click += continueButton_Click;
Events need to be told what they should handle. Without that, they won't "listen" to anything.
Friendly note: be careful when adding handlers "on demand" like this (i.e. outside of the designer). It doesn't really apply here (you have a new button each time), but it's fairly easy to accidentally subscribe to a control's event multiple times, and your handler will fire multiple times as a result. It's just nice to be aware of :)
Some context. I've added inside Page_Load of a class Method1 that generates a repeater and Method2 that generates an array of buttons.
Each button is attached dynamically an event inside Method2.
The buttons will never change, but based on clicking a button the repeated elements should change.
My main problem is/are:
1) when I click a button, the event causes the page to load (Page_Load) which calls Method1, which generates the default repeater, instead of the one associated with my specific event attached to button x from the array of buttons; --> so, I wrapped up Method1 in !isPostBack ... then, nothing happens at all
How would you avoid this? What principles would you use for implementig this?
Attempted so far:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
GetItems(1, 2); //default values (first time the page is loaded)
GenerateButtons(10);
}
}
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].OnClientClick += 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)-1, 3); //3 is a constant; first argument is index of button extracted from its caption
}
//clicking a button should load the page invoking GetItems() specific to the button pressed (first argument is its index) and should regenerate the buttons, maybe highlighting in some way the one that was previously pressed.
To help performance, it would also help not to regenerate the buttons after a page was first loaded.
I'm working with ASP.NET and C#.
My main problem is Button_Click is never invoked, probably because the buttons are regenerated when clicking a button so their definitions is recreated, including the buttons' events.
Your Button_Click handler would always be fired before the regeneration, anyway; so this is not the problem.
Your problem, however, lies in your x[i].OnClientClick += ... code.
You need to hook up to the .Click event of the LinkButton to listen to the right event.
Like this:
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].Click += new EventHandler(Button_Click); // Use the 'Click' event
}
}
Hope this helps!
Any idea how I could make a click event create another button with different click event?
I have a WPF app to make using EF. So I'm stuck at the part where I need to press button "Add" which will freeze other buttons and then create another button "Submit" with code for adding data to the table. I have tried some advice from msdn, but it doesn't work. Here is the code (previously in XAML added a button named b1):
public partial class RoutedEventAddRemoveHandler {
void MakeButton(object sender, RoutedEventArgs e)
{
Button b2 = new Button();
b2.Content = "New Button";
// Associate event handler to the button. You can remove the event
// handler using "-=" syntax rather than "+=".
b2.Click += new RoutedEventHandler(Onb2Click);
root.Children.Insert(root.Children.Count, b2);
DockPanel.SetDock(b2, Dock.Top);
text1.Text = "Now click the second button...";
b1.IsEnabled = false;
}
void Onb2Click(object sender, RoutedEventArgs e)
{
text1.Text = "New Button (b2) Was Clicked!!";
}
I even tried the most obvious solution to simply create another button with click event directly in click event.
I would recommend an alternative approach and put the submitbutton in your xaml code right away but make it so that it is invisible and disabled.
Then in the event handler you simply have to make it visible and enable it.
Your event handler that handles the submit, the dynamic creation of the button, hooking it in the form and such can all be avoided and don't have to be done at runtime.
This will result in a lot better readable code and maintainable code than your original approach unless you have a very good reason for it.
I have done the following coding and it is working for me
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
Button oButton = new Button();
oButton.Name = "btnMessage";
oButton.Content = "Message Show";
oButton.Height = 50;
oButton.Width = 50;
oButton.Click += new RoutedEventHandler(oButton_Click);
//root is a stack panel
root.Children.Insert(root.Children.Count, oButton);
DockPanel.SetDock(oButton, Dock.Top);
}
void oButton_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hello World !");
}
I have a button that is created after a user selects a certain value from a dropdown menu, but it is not firing its' EventHandler. Is there something with the Lifecycle, OnInit possibly, that I have to refresh for the handler to fire correctly?
Event fired from DropDownList's OnSelectedIndexChanged
protected void Selected_floor_first(object sender, EventArgs e)
{
Button btn = new Button();
btn.ID = "room_button_1";
btn.Text = "Select";
btn.Click += new EventHandler(room_1_Click);
floor_1_room_overlay.Controls.Add(btn);
}
Handler: (Not Firing)
protected void room_1_Click(object sender, EventArgs e)
{
validation.Text = "You selected a Room";
}
If you must create your button dynamically, create it inside the OnInit() method of the page.
Event handling happens after Page Init. So, the button will have to be created before Page Init, for the events to be handled.
As it is dynamically added, you have to take that code in Page_Init() event that occurs after every postback. otherwise when the postback occurs, there is no room_button_1 in the forms.controls collection and the event is missed. So
add it as it is being added.
after adding set a variable in session to identify that dynamic control has been added
on page_init() check the session variable of step2. if it says yes then create the control you created in step 1.
Instead of repeating the code, it's better if you create a function for button creation and call it from your Select_floor_first() and Page_Init().
The button goes out of scope mate. define it as a private variable otherwise the event wont fire as the button disposed after Selected_floor_first method finishes
private Button btn = new Button();
protected void Selected_floor_first(object sender, EventArgs e)
{
btn.ID = "room_button_1";
btn.Text = "Select";
btn.Click += new EventHandler(room_1_Click);
floor_1_room_overlay.Controls.Add(btn);
}
protected void room_1_Click(object sender, EventArgs e)
{
validation.Text = "You selected a Room";
}
I have a webusercontrol with a few controls on it like some labels,a textbox and eventually a button. The purpose of this control is to add it to my main page in a placeholder every time I click on the button on the webusercontrol.
This is the code behind my button on my webcontrol
protected void btnCriteriaToevoegen_Click(object sender, EventArgs e)
{
//New eventhandler == all of the eventhandlers of all the objects who have subscribed to the event.
EventHandler eventhandler = ButtonDoorgaan;
ButtonOpslaanEvent mijnevent = new ButtonOpslaanEvent();
//Basic variables I will give with my costum event(ButtonOpslaanEvent)
mijnevent.Naam = txtCriteriumNaam.Text;
mijnevent.Score = Convert.ToInt16(DdlCriteriumScoreSchaal.SelectedValue);
int weging = Convert.ToInt16(DdlCriteriumWeging.SelectedValue) - 1;
mijnevent.Weging = Convert.ToInt16(weging);
//If the eventhandler is not null, for every object that has an eventhandler, execute it.
if(eventhandler!=null)
eventhandler(sender, mijnevent);
}
The eventhandler that need to be executed when the event is fired is defined in my main page like this :
private void critlijn_ButtonDoorgaan(object sender, EventArgs e)
{
ButtonOpslaanEvent eigenevent = (ButtonOpslaanEvent)e;
IEnumerator<Domein> domeinenumerator = domeinen.GetEnumerator();
while (domeinenumerator.MoveNext())
{
if (domeinenumerator.Current.DomeinNaam.Equals(lijstdomeinitemgeselecteerd))
{
Criterium nieuwcriterium = new Criterium();
nieuwcriterium.CriteriumNaam = eigenevent.Naam;
nieuwcriterium.CriteriumScore = Convert.ToString(eigenevent.Score);
nieuwcriterium.CriteriumWeging = Convert.ToString(eigenevent.Weging);
domeinenumerator.Current.Criteriums.Add(nieuwcriterium);
}
}
btnCriteriaToevoegen_Click(sender, e);
}
The btnCriteriaToevoegen_Click event fires and then calls this method(addCriteriaButton()), which will add the button onto the placeholder in my main page:
private void addCriteriaButton()
{
Criterialijn criterialijn = (Criterialijn)LoadControl("~/Criterialijn.ascx");
//Add eventhandlers to control
criterialijn.ButtonDoorgaan += new EventHandler(critlijn_ButtonDoorgaan);
criterialijn.Aangevinkt += new EventHandler(critlijn_Aangevinkt);
//Every control on the page except this one, not enabled
IEnumerator<Criterialijn> criterialijnenumerator = criteriacontrols.GetEnumerator();
while (criterialijnenumerator.MoveNext())
{
criterialijnenumerator.Current.Enabled = false;
}
//Add it to a list of webusercontrols that are currently on screen
criteriacontrols.Add(criterialijn);
criterialijn.Enabled = true;
//Add to placeholder
plhCriteria.Controls.Add(criterialijn);
}
So when all this is said and done, and I run my program, he adds the control to my placeholder, but when I click on the button, he does not add a new control to my placeholder, and just clears my placeholder for some reason. Normally everything should be fine, but I have tried to see if he actually fires the event when you click on the button, and he does not. I have tried to give you a sample of my code, because the code of the whole page is quite big and that would not help you at all. Any ideas why he is not firing the event of the button?
So when your button that you dynamically added posts back, a new page instance is created and that button no longer exists (since you only added it on the previous button click), it has not been recreated.
You must re-create dynamic controls on each postback
Remeber, a new instance of the Page class is created for each postback, any previously created controls, event handlers will not exists in the new instance unless you explicitly re-create them.
I assume these Criteria are some sort of tree structure the user can navigate through (and hopefully arriving at the end somewhere ?).
About btnCriteriaToevoegen_Click:
Why are you defining an event inside a method?
In critlijn_ButtonDoorgaan and addCriteriaButton:
Instead of using an enumerator, just use
foreach(var control in criteriacontrols)
control.Enabled = false;
So yeah, fair to say it's still not quite comprehensable, but it least I tried right? :)
EDIT
ok, then I have this question:
The eventhandler that need to be
executed when the event is fired is
defined in my main page like this :
How sure are you that, when you do
EventHandler eventhandler = ButtonDoorgaan;
the variable "eventhandler" gets all eventhandlers attached to ButtonDoorgaan ?
EDIT 2 (the return)
See Richard Friend's answer; your control is not there anymore