Events Firing Out Of Order Asp.Net - asp.net-2.0

I have a system setup as follows:
User Control Called "Main" when I click a button in "Main" another user control (user control "A", user control "B", user control "C") is populated inside a placeholder of "Main" depending on some logic either A,B, or C is populated.
User controls A,B,C have many buttons on them as well. They Also have a placeholder to contain either user control x, user control y, user control z depending what is clicked inside user control "A" for example.
Main loads controls (A,B, or C) into its placeholder no problem, but when I click a button in A,B,or C to load their placeholder with x,y, or z the whole control (A,B, or C) dissappears.
I understand this has to do with viewstate not holding dynamic controls during a postback. So what I did was explictly called viewstate on the controls loaded into main (A,B,C). when they are loaded I save an entry of what was loaded like this ViewState("lastLoaded")='A' for example. When a postabck occurs (i.e. clicking a button in A) I reload the whole control A.
This is what happens:
I click a button in user control "A"
Postback occurs
User control "A" is reloaded because of the viewstate("lastloaded")
Then I have to click the button in "A" again at that time the button_click event fires
Can someone please help me fix this.
'Here is Main.ascx
Partial Class Main
Inherits System.Web.UI.UserControl
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
ViewState("name") = "ControlA2.ascx"
AddControl(ViewState("name").ToString())
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If ViewState("name") <> String.Empty Then
AddControl(ViewState("name").ToString())
End If
End Sub
Public Sub AddControl(ByVal name As String)
PlaceHolder1.Controls.Clear()
Dim toAdd As Control = LoadControl(name)
PlaceHolder1.Controls.Add(toAdd)
End Sub
Protected Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
ViewState("name") = "ControlB.ascx"
AddControl(ViewState("name").ToString())
End Sub
End Class
'Here is Main designer
Main
asp:Button ID="Button1" runat="server" Text="Add Control A"
asp:Button ID="Button2" runat="server" Text="Add Control B"
asp:PlaceHolder ID="PlaceHolder1" runat="server">
'Here is ControlA2.ascx
Partial Class ControlA2
Inherits System.Web.UI.UserControl
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
PlaceHolder1.Controls.Clear()
Dim toAdd As Control = LoadControl("ControlX.ascx")
PlaceHolder1.Controls.Add(toAdd)
End Sub
End Class
'Here is ControlA2 designer
I am Control A
Add Control X
asp:Button ID="Button1" runat="server" Text="Add Control X"
asp:PlaceHolder ID="PlaceHolder1" runat="server"
/asp:PlaceHolder
'Here is ControlB.ascx
Partial Class ControlA2
Inherits System.Web.UI.UserControl
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
PlaceHolder1.Controls.Clear()
Dim toAdd As Control = LoadControl("ControlZ.ascx")
PlaceHolder1.Controls.Add(toAdd)
End Sub
End Class
'Here is ControlB designer
I am Control B
Add Control Z
asp:Button ID="Button1" runat="server" Text="Add Control Z"
asp:PlaceHolder ID="PlaceHolder1" runat="server" /asp:PlaceHolder
'Here is ControlX.designer
asp:Label ID="Label1" runat="server" Text="Label">I AM CONTROL X /asp:Label
'Here is ControlZ designer
asp:Label ID="Label1" runat="server" Text="Label">I AM CONTROL Z /asp:Label

I've created a project based on your code and I've managed to recreate the issue.
When I initially run it and click on the Add control A button the Main control will load Control A and note this in the viewstate. Control A's button to add Control X will now appear with an id of Main1_ctl00_Button1. When clicking on this button Main's page load will add Control A back to it's placeholder and Control A's button click event will fire. If you now click Main's Control A button again the problem arises. Main's page load method will look at the Viewstate and add control A to the placeholder. Then Main's button click event will then fire clearing the placeholder and re-adding control A. When the form is displayed Control A's button to add Control X will now have an id of Main1_ctl01_Button1 as it was the second control to be generated in the code behind. Now when you click on the button to add control x Main's page load will add Control A again but as it's id will be Main1_ctl00_Button1 and the click event came from a button with an id of Main1_ctl01_Button1 the event will not fire.
To fix this you will have to avoid the duplication of control creation the second time around. You could do this by checking the requests form collection during the page load to see which button was pressed although this is not a very elegant solution. You will need to ensure that the buttons on the Main control have a unique text value for this to work.
Hopefully someone else may be able to come up with a more elegant solution:
Dim mainButtonClick = False
For index As Integer = 0 To Request.Form.Count
If Request.Form(index) = "Button A" Or Request.Form(index) = "Button B" Then
mainButtonClick = True
End If
Next
If Not IsPostBack And Not mainButtonClick And ViewState("name") <> String.Empty Then
AddControl(ViewState("name").ToString())
End If
Please excuse any errors in this code as I am not a VB.NET programmer.

Related

Transfer radio button from webform to another form using VB.net and ASP.net

I wrote the below code which transfer the radio button value and check box value to another HTML form but i did not find solution to transfer the radio button or check box at all to another form not only the selected value.
I want the radio button to be transfered to another form as below not only the value.
enter image description here
Dim Gender As String = RadioButton1.SelectedValue
Response.Redirect("PrintPreview.aspx?"&Gender=" + Gender)
Label1.Text = Request.QueryString("Gender")
The code only returned the radio button value
Please advise
Ok, the FIRST thing, and MOST important thing to realize here is that when you execute a response.Redirect ?
It STOPS code running in the current page.
No code AFTER the Response.Redirect will run
All variables, and code and ALL values for the current page are destroyed!
So, you can't write (normally) code to run after the response.Redirect.
So, say we have this markup:
<br />
<asp:RadioButtonList ID="RadioButtonList1" runat="server"
Font-Size="Larger" RepeatDirection="Horizontal">
<asp:ListItem>Yes</asp:ListItem>
<asp:ListItem>No</asp:ListItem>
</asp:RadioButtonList>
<br />
<asp:Button ID="Button1" runat="server" Text="Done" />
And our page now looks like this:
Now, we want to jump to page 2.
So our code can say look like this in our Test1 page.
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Gender As String = RadioButtonList1.SelectedItem.Text
Response.Redirect("Test2.aspx?&Gender=" & Gender)
' code AFTER above line WILL NOT run!!!!
End Sub
So, we can't have code AFTER the response.Redirect.
Again, read this 5 times:
when the response.Redirect is used, then the current page code STOPS,
and ALL values, and even your code variables are DESTROYED!!! This is not much
different then when you get to the end of a subroutine - when you exit, then all
values and things in that subroutine are "gone", and "do not exist".
The same goes for your web page - using Response.Redirect means STOP code, transfer to another page.
So, now above will jump to page Test2, we want to take that value we passed, and do this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
' save a label on this page to the passed choice
Label1.Text = Request.QueryString("Gender")
End If
End Sub
Also, note close your syntax for the string you were passing in Response.Redirect was also incorrect.

Programatically adding MenuItems triggers Page_load in target URL

I am adding menu items programmatically so I can control which ones appear based on the role of the user. My problem is that every menu item I add behaves as if it has been clicked on during the load. Stripped to bare bones, here is the simplified code:
Public Class test2
Inherits System.Web.UI.Page
Private Sub Page_Init(sender As Object, e As System.EventArgs) Handles Me.Init
If Not IsPostBack Then
CreateMenu()
End If
End Sub
Private Sub CreateMenu()
MainMenu.Items.Add(New MenuItem("Home", "", "/Peak.aspx"))
End Sub
End Class
The test2.aspx contains:
<form id="form1" runat="server">
<asp:Menu ID="MainMenu" runat="server" >
<Items>
</Items>
</asp:Menu>
</form>
This is all the code in Peak.aspx.vb:
Public Class Peak
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
MsgBox("This should not appear but does!!")
End Sub
End Class
The Peak.aspx Page_Load is being loaded and the message box displayed, when test2 is set as the start up page. My real code has several menu items added and CreateMenu causes ALL the page_Loads to be being triggered with a large overhead!
Is this a bug or something I can switch off, and is there a workaround?
You're using this constructor https://msdn.microsoft.com/en-us/library/b00a9c35.aspx
public MenuItem(
string text,
string value,
string imageUrl
)
If you look at it carefully, your third parameter sets imageurl, thus triggering Page_Load event when it tries to load the url. Maybe you wanted to use this overload with 4 parameters? https://msdn.microsoft.com/en-us/library/70k2h50z.aspx
public MenuItem(
string text,
string value,
string imageUrl,
string navigateUrl
)

How to pass value from gridview inside modal pop up extender to textbox in parent form?

I tried to execute below codes to pass selected row value from gridview inside modal pop up extender to textbox in parent form but it doesn't work.
Private Sub GridView1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridView1.SelectedIndexChanged
txttitle.Text = GridView1.SelectedRow.Cells(1).Text
End Sub
Passing values from ajax popup (gridview) to parent page textbox.
This links help you.
http://mattberseth.com/blog/2008/04/masterdetail_with_the_gridview.html
http://mattberseth.com/blog/2007/07/modalpopupextender_example_for.html

Why a private event handler does not work in ASP.NET

Here is the issue:
I have a simple ASP.NET form with 2 buttons.
One of them is created by dragging the button from the tools and the other I created directly in HTML:
<body>
<form id="Form1" method="post" runat="server">
<asp:Button OnClick="ABC" Runat="server" Text="rrr" id="Button1"></asp:Button>
<asp:Button id="Button2" runat="server" Text="Button"></asp:Button>
</form>
</body>
Button2 is created using tools and has the following Event Handler:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim s As String = ""
End Sub
This "Private Event handler runs without any problem.
However for the button which is created under HTML , we have the following event handler:
Private Sub ABC(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim a As Integer = 0
End Sub
For this one I get the following complile error:
Compiler Error Message: BC30390: 'WebApplication9.WebForm1.Private Sub ABC(sender As Object, e As System.EventArgs)' is not accessible in this context because it is 'Private'.
If I change the event handler scope from Private to protected this will work. Question is why private works for one event handler but not the other one.
Basically, an aspx page is implemented as two classes. One of these classes contains your code behind code (.aspx.vb) (and, depending on which version/model of ASP.Net you're using, also some designer generated code (.aspx.designer.vb)).
The second class is created when the page is first requested (or the site is pre-compiled) and contains any inline code from the .aspx page and other code generated by ASP.Net, and includes e.g. code for any controls declared with runat="server".
This second class inherits from the first.
So, if the first class takes responsibility for hooking up its event handlers, it uses a Handles clause*:
Private Sub ABC(...) Handles Button1.Click
Button1 belongs to this class because it was put there by the designer generated code. Everything is local to this class, and so the method can be Private.
If the second class takes responsibility for hooking up an event handler, it does it by using attributes on server controls, such as here:
<asp:Button OnClick="ABC" Runat="server"
Now, unless ABC is a method declared inline inside the .aspx file, it has to be from the first class (or any class from which the first itself inherits from)
We now have a situation where code in the second class wants to refer to code in the first class. And so, the rules of .NET say that the member that it's trying to access cannot be Private.
What you shouldn't have, as you have in your question, is both classes taking responsibility for hooking up the (same) event handlers.
*It doesn't have to use a Handles clause - it could also set up the event handler using AddHandler inside e.g. the Page_Load event, or anywhere else that's appropriate. Handles is idiomatic for static controls on a page in VB. In C#, there's no equivalent to Handles, so the event handlers are hooked up with C#'s equivalent of AddHandler, +=.

Add onclick event to the radio button that added dynamically

I'm creating an online exam page with 30 radiobuttons that are created dynamically at runtime.
How will I get the click event of each radiobutton and tag it in my method that I will check if the next question is need to be jump or escape.
Example:
If I'm in question 10 and answer = "Yes", redirect me to Question 15, else go to the next question
HTML code-
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:Panel ID="RadioButtonsPanel" runat="server" />
</form>
</body>
</html>
VB Code-
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
' Add each radio button
AddNewRaduiButton("MyRadio1")
AddNewRaduiButton("MyRadio2")
AddNewRaduiButton("MyRadio3")
AddNewRaduiButton("MyRadio4")
End Sub
Private Sub AddNewRaduiButton(ByVal name As String)
' Create a new radio button
Dim MyRadioButton As New RadioButton
With MyRadioButton
.ID = name
.AutoPostBack = True
.Text = String.Format("Radio Button - '{0}'", name)
End With
' Add the click event to go to the sub "MyRadioButton_CheckedChanged"
AddHandler MyRadioButton.CheckedChanged, AddressOf MyRadioButton_CheckedChanged
Page.FindControl("RadioButtonsPanel").Controls.Add(MyRadioButton)
End Sub
Protected Sub MyRadioButton_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs)
' Convert the Sender object into a radio button
Dim ClickedRadioButton As RadioButton = DirectCast(sender, RadioButton)
' Display the radio button name
MsgBox(String.Format("Radio Button {0} has been Updated!", ClickedRadioButton.ID))
End Sub
Use the following statement:
AddHandler radioButton.Click, AddressOf instance.MethodName
Refer to How to: Dynamically Bind Event Handlers at Run Time in ASP.NET Web Pages
Also consider using an anonymous sub (VB2010 only) to write the event handler inline
AddHandler radioButton.Click,
Sub(s As Object, e As EventArgs)
MessageBox.Show("Awesome!")
End Sub
Adapted from here
You can also use closures...

Resources