Help with user controls within PlaceHolders.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • CroCrew
    Recognized Expert Contributor
    • Jan 2008
    • 564

    #1

    Help with user controls within PlaceHolders.

    Hello all,

    Thanks for looking at my post and thank to anyone that provides me with the help I am looking for.

    I dynamically load user controls from a default page but when a postback fires within the user controls I can’t get the selected user control to reload. Hard to explain so I will try to show you what is going on.

    Default1.aspx
    Code:
    <%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default1.aspx.vb" Inherits="Default1" %> 
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    <html xmlns="http://www.w3.org/1999/xhtml"> 
        <head runat="server"> 
            <title></title> 
        </head> 
        <body> 
            <form id="form1" runat="server"> 
                <asp:PlaceHolder runat="server" ID="myPlaceHolder"> 
                    Welcome please select a option. 
                </asp:PlaceHolder> 
                <p> 
                    <asp:LinkButton id="LinkButton1" runat="server">Say Hello</asp:LinkButton><br /> 
                    <asp:LinkButton id="LinkButton2" runat="server">Say Goodbye</asp:LinkButton><br /> 
                </p> 
            </form> 
        </body> 
    </html>
    Default1.aspx.v b
    Code:
    Partial Class Default1 
        Inherits System.Web.UI.Page 
      
        Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LinkButton1.Click 
            myPlaceHolder.Controls.Clear() 
            myPlaceHolder.Controls.Add(LoadControl("Hello.ascx")) 
        End Sub 
      
        Protected Sub LinkButton2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LinkButton2.Click 
            myPlaceHolder.Controls.Clear() 
            myPlaceHolder.Controls.Add(LoadControl("Goodbye.ascx")) 
        End Sub 
    End Class
    When I click on the link “Say Hello” the user control “Hello.asc x” does load in the placeholder just fine.

    Hello.ascx
    Code:
    <%@ Control Language="VB" AutoEventWireup="false" CodeFile="Hello.ascx.vb" Inherits="Hello" %> 
    What is your name? <asp:TextBox ID="TextBox1" runat="server"/> 
    &nbsp;&nbsp; 
    <asp:Button ID="Button1" runat="server" Text="Answer" /> 
    <br /> 
    <br /> 
    <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
    Hello.ascx.vb
    Code:
    Partial Class Hello 
        Inherits System.Web.UI.UserControl 
      
        Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click 
            Label1.Text = "Hello " & TextBox1.Text 
        End Sub 
    End Class
    When I enter my name and click the “Answer” button the page reloads back to the original state with no user control loaded. Why is the “Hello.asc x” user control not loaded with “Lable1” populated with the information for the click event from the code behind event?

    Can someone tell me why?

    Thanks,
    CroCrew~
  • yarbrough40
    Contributor
    • Jun 2009
    • 320

    #2
    Hey cro. try regestering the control in the default page
    Code:
    <%@ Register TagPrefix="MyControl" TagName="MyControl" Src="~/Hello.ascx" %>
    then when you load the control in the code behind, call it by its tag "MyControl"
    -see if that works

    Comment

    • CroCrew
      Recognized Expert Contributor
      • Jan 2008
      • 564

      #3
      Thanks for the reply yarbrough40.

      I know how to use the <%@ Register %> to add includes. But, to dynamically loading specific user controls at run time within a placeholder using the <%@ Register %> I have not done.

      I would think that after registering the control I could just use this syntax: myPlaceHolder.C ontrols.Add(Loa dControl(MyCont rol)) within the click event but that does not work.

      Do I have the correct syntax?

      Default1.aspx
      Code:
      <%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default1.aspx.vb" Inherits="Default1" %> 
      <%@ Register TagPrefix="MyControl" TagName="MyControl" Src="~/Hello.ascx" %> 
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
      <html xmlns="http://www.w3.org/1999/xhtml">  
          <head runat="server">  
              <title></title>  
          </head>  
          <body>  
              <form id="form1" runat="server">  
                  <asp:PlaceHolder runat="server" ID="myPlaceHolder">  
                      Welcome please select a option.  
                  </asp:PlaceHolder>  
                  <p>  
                      <asp:LinkButton id="LinkButton1" runat="server">Say Hello</asp:LinkButton>
                  </p>  
              </form>  
          </body>  
      </html>
      Default1.aspx.v b
      Code:
      Partial Class Default1  
          Inherits System.Web.UI.Page  
        
          Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LinkButton1.Click  
              myPlaceHolder.Controls.Clear()  
              myPlaceHolder.Controls.Add(LoadControl(MyControl))  
          End Sub  
      End Class
      Thanks,
      CroCrew~

      Comment

      • yarbrough40
        Contributor
        • Jun 2009
        • 320

        #4
        hmmm - I see. I also have not done what you are attempting. later on today I will see if I can get it to work if you are still failing. In your code behind try first instantiating the new control and then adding that.
        If you were to put it in the page directly as opposed to loading it at runtime I believe it would need to look like this:
        Code:
        <MyControl:MyControl runat="server" />
        so an instantiation of exactly this somehow might do the trick

        Comment

        • CroCrew
          Recognized Expert Contributor
          • Jan 2008
          • 564

          #5
          Correct. That is how I add my headers and footers to my pages. But, as you can see I am trying to dynamically loading specific user controls at run time within a placeholder using a click event.

          I will keep on trying things to see if I can figure it out.

          I do thank you for your help. If you figure out anything please let me know.

          Thanks again,
          CroCrew~

          Comment

          • yarbrough40
            Contributor
            • Jun 2009
            • 320

            #6
            do you know for sure that the placeholder is the issue? if you try to load your control elsewhere in the form does it still fail to persist?

            Comment

            • CroCrew
              Recognized Expert Contributor
              • Jan 2008
              • 564

              #7
              Using <MyControl:MyCo ntrol runat="server" /> to add a control on a page would work but, not how I want it to work.

              The issue is I want to change out the text within the placeholder to a user control and within the user control there is a textbox that when you enter your name in it and click the submit button the code behind on the user control would process something. As it is now after you click the submit button in the user control the parent page reloads to its original state.

              Comment

              • CroCrew
                Recognized Expert Contributor
                • Jan 2008
                • 564

                #8
                What I am trying to do is from the parent page have a few links that would do a postback and based on the link chosen a user control would then be loaded within a placeholder on the parent page. All that works fine.

                The part that I just can’t seem to figure out is how to process the code behind for the user control if a click event is fired from the loaded user control. On any postback from a user control all I get is the parent page reloading to its original state.

                I am about 65% in thinking it can’t be done.

                Comment

                • yarbrough40
                  Contributor
                  • Jun 2009
                  • 320

                  #9
                  Ok so I did some playing around. It works if you store the control name in viewstate and then call it back on page load
                  Code:
                  Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LinkButton1.Click
                          LoadHello()
                      End Sub
                  
                      Private Sub LoadHello()
                          Dim mc As Control = LoadControl("Hello.ascx")
                          myPlaceHolder.Controls.Clear()
                          myPlaceHolder.Controls.Add(mc)
                          ViewState.Add("MyControl", "Hello.ascx")
                          SaveViewState()
                      End Sub
                  
                      Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
                  
                          If IsPostBack Then
                              Dim ControlName As String = ViewState("MyControl")
                              If Not ControlName Is Nothing Then
                                  Dim control As Control = LoadControl(ControlName)
                                  myPlaceHolder.Controls.Add(control)
                              End If
                          End If
                  
                      End Sub
                  ROCK!

                  Comment

                  • CroCrew
                    Recognized Expert Contributor
                    • Jan 2008
                    • 564

                    #10
                    WONDERFUL!! That is exactly what I was looking to do.

                    Yarbrough40 you ROCK!!

                    Comment

                    • CroCrew
                      Recognized Expert Contributor
                      • Jan 2008
                      • 564

                      #11
                      Oh and congratulations on your 200 post!

                      Comment

                      • yarbrough40
                        Contributor
                        • Jun 2009
                        • 320

                        #12
                        lol! 200 posts with an answer. it's like providence : )

                        Comment

                        • CroCrew
                          Recognized Expert Contributor
                          • Jan 2008
                          • 564

                          #13
                          After a week of testing I have found a bug but can’t seem to understand why this bug is happening. Below is the code for the two pages and here are the steps to trigger the bug.

                          Steps:
                          1. Click on the “Say Hello” LinkButton.
                          2. Enter your name and click the “Answer” button.
                          3. You should see a message saying “Hello {your name}”. This works fine.
                          4. Click on the “Say Hello” LinkButton again.
                          5. Enter your friends name and click the “Answer” button.
                          6. You should see a message saying “Hello {your friend’s name}” but it does not unless you type your friends name again.

                          The bug is after the second time you click on the “Say Hello” LinkButton.

                          Any advice on fixing this bug?

                          Thanks,
                          CroCrew~

                          Default.aspx
                          Code:
                          <%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
                          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
                          <html xmlns="http://www.w3.org/1999/xhtml">  
                              <head id="Head1" runat="server">  
                                  <title></title>  
                              </head>  
                              <body>  
                                  <form id="form1" runat="server">  
                                      <asp:PlaceHolder runat="server" ID="myPlaceHolder">  
                                          Welcome please select a option.  
                                      </asp:PlaceHolder>  
                                      <p>  
                                          <asp:LinkButton id="LinkButton1" runat="server">Say Hello</asp:LinkButton><br />  
                                      </p>  
                                  </form>  
                              </body>  
                          </html>
                          Default.aspx.vb
                          Code:
                          Partial Class _Default
                              Inherits System.Web.UI.Page
                          
                              Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
                                  If IsPostBack Then
                                      Dim ControlName As String = ViewState("MyControl")
                                      If Not ControlName Is Nothing Then
                                          Dim control As Control = LoadControl(ControlName)
                                          myPlaceHolder.Controls.Clear()
                                          myPlaceHolder.Controls.Add(control)
                                      End If
                                  End If
                              End Sub
                          
                              Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LinkButton1.Click
                                  Dim mc As Control = LoadControl("Hello.ascx")
                                  myPlaceHolder.Controls.Clear()
                                  myPlaceHolder.Controls.Add(mc)
                                  ViewState.Add("MyControl", "Hello.ascx")
                                  SaveViewState()
                              End Sub
                          End Class
                          Hello.ascx
                          Code:
                          <%@ Control Language="VB" AutoEventWireup="false" CodeFile="Hello.ascx.vb" Inherits="Hello" %>
                          What is your name? <asp:TextBox ID="TextBox1" runat="server"/>  
                          &nbsp;&nbsp;  
                          <asp:Button ID="Button1" runat="server" Text="Answer" />  
                          <br />  
                          <br />  
                          <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
                          Hello.ascx.vb
                          Code:
                          Partial Class Hello
                              Inherits System.Web.UI.UserControl
                          
                              Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
                                  Label1.Text = "Hello " & TextBox1.Text
                              End Sub
                          End Class

                          Comment

                          • yarbrough40
                            Contributor
                            • Jun 2009
                            • 320

                            #14
                            it looks as though the problem is occurring from re-adding the control after the control has been added. What then occurs is that you end up Clearing the controls and adding it back (in the page load) THEN Clearing and adding again (in the Link Button Event). Unsure why, but when this happens, your button click event in the ascx control does not fire.
                            Try these two adjustments and see if it suites your needs:

                            Default.aspx.vb
                            Code:
                             Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LinkButton1.Click
                            
                                    Dim ControlName As String = ViewState("MyControl")
                            
                                    If ControlName Is Nothing Then
                                        Dim mc As Control = LoadControl("Hello.ascx")
                                        myPlaceHolder.Controls.Clear()
                                        myPlaceHolder.Controls.Add(mc)
                                        ViewState.Add("MyControl", "Hello.ascx")
                                        SaveViewState()
                                        mc.EnableViewState = True
                                    End If
                            
                                End Sub
                            Hello.ascx.vb
                            Code:
                            Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
                                    Label1.Text = "Hello " & TextBox1.Text
                                    TextBox1.Text = ""
                                End Sub

                            Comment

                            • CroCrew
                              Recognized Expert Contributor
                              • Jan 2008
                              • 564

                              #15
                              Thanks Yarbrought40,

                              That works when reloading the “same” control. But, when I add the ability for more controls it will only load the first control.

                              See below code (Goodbye.ascx is the same as Hello.ascx but is just says goodbye instead):

                              Default.aspx
                              Code:
                              <%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
                              <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
                              <html xmlns="http://www.w3.org/1999/xhtml">  
                                  <head id="Head1" runat="server">  
                                      <title></title>  
                                  </head>  
                                  <body>  
                                      <form id="form1" runat="server">  
                                          <asp:PlaceHolder runat="server" ID="myPlaceHolder">  
                                              Welcome please select a option.  
                                          </asp:PlaceHolder>  
                                          <p>  
                                              <asp:LinkButton id="LinkButton1" runat="server">Say Hello</asp:LinkButton><br />  
                                              <asp:LinkButton id="LinkButton2" runat="server">Say Goodbye</asp:LinkButton><br />  
                                          </p>  
                                      </form>  
                                  </body>  
                              </html>
                              Default.aspx.vb
                              Code:
                              Partial Class _Default
                                  Inherits System.Web.UI.Page
                              
                                  Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
                                      If IsPostBack Then
                                          Dim ControlName As String = ViewState("MyControl")
                                          If Not ControlName Is Nothing Then
                                              Dim control As Control = LoadControl(ControlName)
                                              myPlaceHolder.Controls.Clear()
                                              myPlaceHolder.Controls.Add(control)
                                          End If
                                      End If
                                  End Sub
                              
                                  Sub SetControl(ByVal ControlPage As String)
                                      Dim ControlName As String = ViewState("MyControl")
                              
                                      If ControlName Is Nothing Then
                                          Dim mc As Control = LoadControl(ControlPage)
                                          myPlaceHolder.Controls.Clear()
                                          myPlaceHolder.Controls.Add(mc)
                                          ViewState.Add("MyControl", ControlPage)
                                          SaveViewState()
                                          mc.EnableViewState = True
                                      End If
                                  End Sub
                              
                                  Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LinkButton1.Click
                                      SetControl("Hello.ascx")
                                  End Sub
                              
                                  Protected Sub LinkButton2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LinkButton2.Click
                                      SetControl("Goodbye.ascx")
                                  End Sub
                              End Class

                              Comment

                              Working...