Ankit Srivastava
Ankit Srivastava

Reputation: 1

Adding thousands of Usercontrols to Stackpanel at run time in WPF using Virtualization

(May be I am really stupid for asking this really silly question but I would sincerely appreciate a detailed help with some sample code please)

I am very new to programming and specially very new to WPF. This is my first WPF application and therefore I have no knowledge related to MVVM. So please do not link this question to MVVM, as that is another topic and I am trying to learn that as well. I want to solve this problem without MVVM.

Brief about existing code:

I have a usercontrol (people_tile), nothing fancy, just a bunch of Labels, having different font sizes, different appearances, etc. when I create an object of this usercontrol I change the content of one of the labels to the ID value which is there in the database. The remaining things happen inside the usercontrol, when it loads. I am sure, the experience programmers would remember their starting days and laugh at me, but i am still learning.

Now when it comes to bringing this usercontrol on the screen, I have a stackpanel approach. When the user clicks on a button on the main screen, another usercontrol opens on the page. this usercontrol (people_page) has a stackpanel in it, which is loaded with the people_tile usercontrol. I am not very good with Binding, so all that I am doing is running a for loop, passing the ID value to the object created for the people_tile usercontrol and then adding this people_tile control as a child to the stack panel available on the people_page usercontrol.

Problem Statement

All this works absolutely fine, and no issues or problems, except that when the data increases, it takes a very long time for adding people_tile usercontrol to the stackpanel control of the people_page usercontrol. Currently i have approximately 1200 items in the people table. But the problem starts as early as 500 items itself. It take a very huge amount of time to create those many usercontrols inside the panel.

Help Required

How do I use Virtualization here. I have tried VirtualizingStackpanels as an option by reading other posts, but i think it means nothing if we are not using Binding, so basically if any one can help me in the following

  1. Loading list of my usercontrols using Binding (i think the terms used is observable collection but I might be completely wrong here)

  2. Loading this list of usercontrols either as a ListBox, or directly in my Panel, or through ItemsControl, whichever is the most preferred way

  3. Please note that the datacontext of the usercontrol should be the usercontrol itself as the other data that I am filling inside the usercontrol uses the Datacontext = Me statement defined in the initialize sub of the people_tile usercontrol only.

  4. Lastly there is a click event on the Usercontrol that does a lot of things seperately in the code. We need to retain that as well. What I mean is, if we use ListBox for holding the usercontrols then I might loose the click functionality of the individual usercontrols. I do not want that.

Sincere request: I am not familiar or proficient with Binding that much, so please if you are mentioning Binding then please also tell me what and where i need to do the change in my code

Some Code References for things I have tried with ListBox approach

In the XAML i have created

     <ListBox x:Name="ListBox_Main">

            <ListBox.ItemTemplate>
                <DataTemplate>
                    <local:UserControl_Tile_People/>
                </DataTemplate>
            </ListBox.ItemTemplate>               
            
     </ListBox>

In the Code behind I have this

Dim items As List(Of UserControl_Tile_People) = New List(Of UserControl_Tile_People)()

    For row_cntr = 0 To global_dt_people_master_list.Rows.Count - 1

        Dim objTile As New UserControl_Tile_People
        objTile.lblPerson_id.Content = global_dt_people_master_list.Rows(row_cntr).Item("bp_id").ToString
        objTile.DataContext = objTile

        items.Add(New UserControl_Tile_People() With {
                  .id_value_passed = global_dt_people_master_list.Rows(row_cntr).Item("bp_id").ToString
                  })

    Next


    Me.ListBox_Main.ItemsSource = items

This does not give me any virtualization. It does not load the usercontrols either. the code for my user control is as follows

XAML Part

And Code behind for Usercontrol

    Private Sub UserControl_Tile_People_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded  
    Me.lblPerson_id.Content = id_value_passed
    lbl_person_id_changed()
    End Sub


    Public Sub lbl_person_id_changed()
    Dim id_value As String = ""
    If Me.lblPerson_id.Content <> "0" Then
        id_value = Me.lblPerson_id.Content
        prp_Person_Print_Name = id_value
        prp_Mobile_Number = id_value
        prp_LRP_Points = id_value
        prp_LRP_cadre = id_value
        prp_Person_Type = id_value
    End If
    End Sub

    Dim pvt_Person_Print_Name As String
    Public Property prp_Person_Print_Name As String
    Get
        Return pvt_Person_Print_Name
    End Get
    Set(value As String)
        pvt_Person_Print_Name = value
        
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("Prp_Person_Print_Name"))
    End Set
    End Property

I was able to solve it myself, without using any MVVM. Thanks for all the support.

Upvotes: 0

Views: 235

Answers (1)

Ankit Srivastava
Ankit Srivastava

Reputation: 1

I was able to solve it myself, without using any MVVM. Thanks for all the support.

I just figured out what Clemens was trying to tell me.

Thanks Clemens, for all the guidance. Really appreciate it.

Upvotes: -1

Related Questions