?
Solved

Display order of asp.net dynamic multiple instances  user controls

Posted on 2011-05-11
9
Medium Priority
?
408 Views
Last Modified: 2012-08-13
Hi

I have a from with a button and a placeholder. I am adding a dynamic usercontrol to the page
every time the button is clicked. When the button is first clicked the control is added into the holder.
When it is clicked a second time another user control appears under the first. What I need to do is change that order. When the button is clicked a second time I need to add the control in the holder on top of the first on instead below. So that the last control added is always first.

I use viewstate to track number of control added and Page_PreLoad to add the controls.
Click event of button
 
Protected Sub btnAddTestRun_Click(sender As Object, e As System.EventArgs) Handles btnAddTestRun.Click
        If (CInt(ViewState("TestRunCounter")) = 0) Then
            Dim ts As UserControls_TestRun = CType(Page.LoadControl("~/UserControls/TestRun.ascx"), UserControls_TestRun)
            ts.HeaderId = 12419
            phTestRun.Controls.Add(ts)
        End If
        ViewState("TestRunCounter") = CStr(CInt(ViewState("TestRunCounter")) + 1)
    End Sub

Open in new window


Page_PreLoad
 
Protected Sub Page_PreLoad(sender As Object, e As System.EventArgs) Handles Me.PreLoad
        If (CInt(ViewState("TestRunCounter")) > 0) Then
            For trc As Int32 = 0 To ViewState("TestRunCounter")
                Dim ts As UserControls_TestRun = CType(Page.LoadControl("~/UserControls/TestRun.ascx"), UserControls_TestRun)
                ts.HeaderId = 12419
                phTestRun.Controls.Add(ts)
            Next

        End If
        If (ViewState("TestRunCounter") = Nothing) Then
            ViewState("TestRunCounter") = "0"
        End If
    End Sub

Open in new window


I'm not sure Im even doing this correctly
0
Comment
Question by:Strychtur
  • 4
  • 4
9 Comments
 
LVL 16

Expert Comment

by:Kamal Khaleefa
ID: 35745158
hi
  when you the second one by default it will come the second
so what u have to do is to make some replacements
like
copy the first one added into a temporary object
add the second
then restore the first object and add it .....
0
 
LVL 17

Expert Comment

by:Jesse Houwing
ID: 35745406
Instead of using Add, use AddAt() which allows you to specify the index. 0 would put it at the top and move the other controls down a notch.
http://msdn.microsoft.com/en-us/library/system.web.ui.controlcollection.addat(v=VS.71).aspx
0
 

Author Comment

by:Strychtur
ID: 35746350
Hi

I think I may need a combination of both
Here is what I need to accomplish.
Lets say each newly added control represents a test run.
When the first one is added I check the db for the last test run
for that client then I add 1 to it.
 test run
So then user fills in test run hits save. test run is saved.
When user clicks add another test run I want to add another test run user control with the right number but still keep the first one on the page. I hope this is clear.

I'm not sure how to load an object or control with is data into memory then reload it

Need URGENT help please
Thanks for the time
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 17

Expert Comment

by:Jesse Houwing
ID: 35746481
You'll need to store the list of testruns to be stored in the ControlState, that way you can add the controls again dynamically when reloading the page. This is one of the most difficult subjects in the ASP.NET page lifecycle. If you search Google/Bing for "Dynamically created controls postback (viewstate OR controlstate)" you should find a lot of atricles pointing you in the right direction.

It basically comes down to the fact that you need to store enough information on the controls in the ControlState (or ViewState isa you're using an older version of the Framework) to restore the control tree upon postback. You only need to create the controls and give them the same ID as you gave them before the postback. The controls should then automatically load their values from the postback data and the viewstate/controlstate.
0
 

Author Comment

by:Strychtur
ID: 35748319
Thanks

I did some research but could not find anything on multiple instances of the same dynamic user control. control. and I still don't understand how I can load a control from viewstate or controlstate
0
 
LVL 17

Accepted Solution

by:
Jesse Houwing earned 2000 total points
ID: 35749712
You can load a usercontrol dynamically using Usercontrol.LoadControl(), you'll need to store a list of id's or at least the number of dynamically loaded controls in the viewstate, so that you can create these controls again when the page is posted back to the server. The issue is, that this is one of the most complex parts in ASP.NET webforms. In oder to get this workign without any issues you'll have to dig deep and you'll have to understand exactly what is going on.

What you're after in a nutshell:
- when the button is clicked (or another event which causes a new item in the list), use
var control = (YourUserControl) UserControl.LoadControl("~/path/to/YourUserControl.ascx");
control.Id = "TestRun_" + testrunId;
PlaceHolder.Controls.AddAt(0, control);
TestRuns.Add(testrunId);
// set your properties here


- You'll need to store theses testrunId's somewhere:
public List<int> TestRuns
{
     get { if (ViewState["TestRuns"] != null) { ViewState["TestRuns"] = new List<int>(); }
     return (List<int>)ViewState["TestRuns"]; }
}

- You'll need to override the CreateChildControls method to ensure the usercontrols are loaded
public override void CreateChildControls()
{
      foreach (var testrun in TestRuns.Reverse())
      {
           var control = (YourUserControl) UserControl.LoadControl("~/path/to/YourUserControl.ascx");
           control.Id = "TestRun_" + testrunId;
           PlaceHolder.Controls.Add(control);
      }
}

If you have viewstate enabled on your page and on your usercontrols, they should automatically reload the data upon postback.
0
 

Author Comment

by:Strychtur
ID: 35750347
Thanks.

Ok here is what I have
 
Protected Sub btnAddTestRun_Click(sender As Object, e As System.EventArgs) Handles btnAddTestRun.Click
        Dim testRunCtnl As UserControls_TestRun = CType(Page.LoadControl("~/UserControls/TestRun.ascx"), UserControls_TestRun)
        testRunCtnl.HeaderId = 12419 'pumpTestBO.PumpTestID
        testRunBO = New TestRunBO()
        testRunCtnl.TestNum = testRunBO.GetNewRunNumber(testRunCtnl.HeaderId)
        RunCouter += 1
        testRunCtnl.ID = "TestRun_" + RunCouter.ToString
        phTestRun.Controls.AddAt(0, testRunCtnl)
        TestRuns.Add(RunCouter)
    End Sub

Open in new window

Click event of button

 
Protected Overrides Sub CreateChildControls()
        If Not TestRuns Is Nothing Then
            If TestRuns.Count > 0 Then
                TestRuns.Reverse()
                For Each testrun In TestRuns
                    'Dim control = DirectCast(UserControl.LoadControl("~/path/to/YourUserControl.ascx"), YourUserControl)
                    Dim testRunCtnl As UserControls_TestRun = CType(Page.LoadControl("~/UserControls/TestRun.ascx"), UserControls_TestRun)
                    testRunCtnl.ID = "TestRun_" & testrun
                    phTestRun.Controls.Add(testRunCtnl)
                Next
            End If
        End If
    End Sub

Open in new window

ChildOverRide

 
Public ReadOnly Property TestRuns() As List(Of Integer)
        Get
            If ViewState("TestRuns") IsNot Nothing Then
                ViewState("TestRuns") = New List(Of Integer)()
            End If
            Return DirectCast(ViewState("TestRuns"), List(Of Integer))
        End Get
    End Property

Open in new window

List

When I try TestRuns.Add(RunCounter) if errors Object reference not set to an instance of an object

not sure why
0
 

Author Comment

by:Strychtur
ID: 35750467
TestRuns is nothing Why?
0
 
LVL 17

Expert Comment

by:Jesse Houwing
ID: 35752957
If ViewState("TestRuns") IsNot Nothing Then
                ViewState("TestRuns") = New List(Of Integer)()
            End If

should be

If ViewState("TestRuns") Is Nothing Then
                ViewState("TestRuns") = New List(Of Integer)()
            End If
0

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

User art_snob (http://www.experts-exchange.com/M_6114203.html) encountered strange behavior of Android Web browser on his Mobile Web site. It took a while to find the true cause. It happens so, that the Android Web browser (at least up to OS ver. 2.…
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …
With just a little bit of  SQL and VBA, many doors open to cool things like synchronize a list box to display data relevant to other information on a form.  If you have never written code or looked at an SQL statement before, no problem! ...  give i…
Suggested Courses
Course of the Month16 days, 16 hours left to enroll

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question