开发者

Events Firing Out Of Order Asp.Net

开发者 https://www.devze.com 2022-12-15 17:45 出处:网络
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

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

Ma开发者_如何学运维in 

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消