Evgenie Tivaniuk

Evgenie Tivaniuk

  • NA
  • 82
  • 11.8k

Dynamically created button refreshes the page instead of doing as due

Jan 8 2021 4:31 PM

I am slowly getting into ASP.NET, currently trying to make a small webforms app for a hackathon.   

The page that I am having problems with is supposed to show a list of companies to which person can apply. Since the list of those companies can change, company always can be added or removed, I want to make some kind of table which loads values dynamically.
 
The table appears when a user clicks "View all companies", it shows a table with each row including the name of company and a button to move to the page of this company. At this stage, I am trying to make something even more simple, for the sake of testing. So, the button should just display some kind of text.

But here's the problem. When I click on the button, it just resets the page and as I understand, runs "Page_Load". The text is also resets to the value from Page_Load. 

Now, I'll try to give code and try to give the best descriptions.

Here's the Page_Load, it just displays the name of the user, and hides the table with company names.

  1. protected void Page_Load(object sender, EventArgs e)  
  2. {  
  3.         if (thisUser == null)  
  4.             lblWelcomeUser.Text = "Welcome";  
  5.         else  
  6.             lblWelcomeUser.Text = "Welcome, " + thisUser.FirstName + " " + thisUser.LastName;  
  7.   
  8.         pnlCompaniesView.Visible = false;  

The code for showing all companies comes here:
  1. protected async void btnViewAllCompanies_Click(object sender, EventArgs e)    
  2. {    
  3.     ResetCompaniesTable();    
  4.     
  5.     lblWelcomeUser.Text = "ViewAll";    
  6.     
  7.     FirebaseResponse response = await HRGlobalHub.Code.Start.Firebase.thisFirebaseClient.GetTaskAsync("HRGlobalHub/Database/Companies/CompaniesList/");    
  8.     
  9.     HRGlobalHub.Code.Company.CompaniesNamesList thisData = response.ResultAs<HRGlobalHub.Code.Company.CompaniesNamesList>();    
  10.     string[] CompanyArray = thisData.CompanyNameListVar.Split(',');    
  11.     
  12.     for (int i = 1; i < CompanyArray.Length; i++)    
  13.     {                   
  14.         response = await HRGlobalHub.Code.Start.Firebase.thisFirebaseClient.GetTaskAsync("HRGlobalHub/Database/Companies/CompaniesDatabase/" + CompanyArray[i]);    
  15.         HRGlobalHub.Code.Company.Company result = response.ResultAs<HRGlobalHub.Code.Company.Company>();    
  16.     
  17.         tbtTestTable.Rows.Add(NewCompanyRow(result));                    
  18.     }    
  19.     
  20.     pnlCompaniesView.Visible = true;    
  21.     pnlCompaniesView.Width = 1100;    
  22.     tbtTestTable.Width = 1100;    
  23.     lblWelcomeUser.Text = tbtTestTable.Visible.ToString();    
  24. }
It loads first just the names of companies, then full companies data from the server. Each company turns into a table row. This part works so far. As you can see, the button_click also should get the Company that is in use.:
  1. public TableRow NewCompanyRow(HRGlobalHub.Code.Company.Company thisCompany)  
  2. {  
  3.     TableRow newRow = new TableRow();  
  4.   
  5.     Button btnApply = new Button();  
  6.     btnApply.Text = "Apply";  
  7.     btnApply.Click += (sender, EventArgs) => { btnApplyClick(sender, EventArgs, thisCompany); };            
  8.   
  9.     TableCell Cell0 = new TableCell();  
  10.     TableCell Cell1 = new TableCell();  
  11.   
  12.     Cell0.Text = thisCompany.Name;  
  13.     Cell1.Controls.Add(btnApply);  
  14.   
  15.     Cell0.Width = 150;  
  16.     Cell1.Width = 150;  
  17.       
  18.     newRow.Cells.Add(Cell0);  
  19.     newRow.Cells.Add(Cell1);  
  20.   
  21.     btnApply.Width = 150;  
  22.       
  23.     return newRow;  

Again, since it's just testing stage for this page, the button should only display the name of the company that it gets as variable.
  1. void btnApplyClick(Object sender, EventArgs e, HRGlobalHub.Code.Company.Company thisCompany)    
  2. {    
  3.     lblWelcomeUser.Text = "Apply to " + thisCompany.Name;                
  4. }   
And here is the problem: instead of doing what appears in the method, it just resets the page. And it doesn't matter what I try to do, display a text, go to another page, change a variable, save data to server, it doesn't work.
 
I spent two days trying to solve it, was actively googling. Tried using static variables in same class, and in another one, tried saving data to server, trying declaring button as global variables in the relevant window class.
If I declare just one button as global class variable, then assign it to the table, it does work, but only with just one button involved. With two of them, the code always goes for the last one.
 
Many of my searches for solutions, and the only answer I got from Stack Overflow was to use something called "PostBack", but I still can't understand what it is, and how to use it.
 
As I understand, the idea is to run the required method at Page Load. But how I can make sure that the relevant method is used? All my attempts to store the data failed: global variables are reset, and any attempts to use buttons to store the data on server on another class, completely failed.
 
I tried following: 
  1. async void btnApplyClick(Object sender, EventArgs e, HRGlobalHub.Code.Company.Company thisCompany)  
  2. {   
  3.     var newMI = new HRGlobalHub.Code.MainInterface.MI  
  4.     {  
  5.         Id = "MI",  
  6.         Action = "Apply",  
  7.         IsEmpty = false,  
  8.         UsedCompanyName = thisCompany.Name  
  9.     };  
  10.   
  11.     SetResponse response = await HRGlobalHub.Code.Start.Firebase.thisFirebaseClient.SetTaskAsync("HRGlobalHub/MI/" + newMI.Id, newMI);  

I hoped to load the MI at age Load, but as was expected, the method simply doesn't run.
 
I tried to create  Lists of button variables then trying to change them at the stage when table is created. I didn't save exact code, but it was something lie:
  1. Buttons.Add(new Button());  
  2. Buttons[Buttons.Count-1].Text = "Apply";  
  3. Buttons[Buttons.Count-1].Click += (sender, EventArgs) => { btnApplyClick(sender, EventArgs, thisCompany);}; 
I guess, I can use the dumb method and instead of using dynamic buttons create a table with 1000 of them, and set an own void to each, then hide empty lines, but this isn't really the solution, it's a way to go around it, and quite silly one.
 
Please help, I can't solve it on my own.
 
Thank you,
Evgenie

Answers (6)