Results 1 to 20 of 20

Thread: [RESOLVED] Runtime Item Collection Initialization

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Jan 2022
    Posts
    211

    Resolved [RESOLVED] Runtime Item Collection Initialization

    Hello, First I mention I dont have any issues (well none that are related to computers anyway)

    Ive always been a bit curious as to why databound controls Items are not available until the control is added to the Form itself.

    Code for example:
    Code:
    Private Sub FormListBox_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim DT As New DataTable
        With DT
            .Columns.Add(New DataColumn With {
                         .ColumnName = "Val",
                         .DataType = GetType(Int64),
                         .AutoIncrement = True})
            .Columns.Add(New DataColumn With {
                         .ColumnName = "Str",
                         .DataType = GetType(String)})
            For i As Integer = 1 To 10
                .Rows.Add(New Object() {i, "str" & i.ToString})
            Next
        End With
    
        Dim Lbox As New ListBox With {
            .DataSource = DT,
            .ValueMember = "Val",
            .DisplayMember = "Str"}
    
        'Lbox.Items.Count = 0
        Controls.Add(Lbox)
        'Lbox.Items.Count = 10
    End Sub

  2. #2
    Frenzied Member
    Join Date
    Apr 2016
    Posts
    1,415

    Re: Runtime Item Collection Initialization

    Hi,

    Your code creates a dataTable, fill it with data and then it creates a listbox and binds it to the dataTable.

    At this point the ListBox is not connected to the form and doesn't know what data to display so it's empty until it is added to the form. When the listox is added it connects to the data and shows the data in the ListBox

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Jan 2022
    Posts
    211

    Re: Runtime Item Collection Initialization

    At this point the ListBox is not connected to the form and doesn't know what data to display so it's empty until it is added to the form
    Hey there, thanks for your input.

    I am rather looking for a more technical/procedural explanation, however. The routine is within the Form Class, so what you've mentioned could be subject to debate. Its got something to do with the visibility of the ListBox itself. You can put the ListBox in any container that is on the Form by any means, and if that container is not visible the LisBox collection is still empty. It is not until the ListBox is added to a parent container and is visible and is on the form does the Collection become available.

    Seems there is something in the .Visible method that initiates the collection.

  4. #4
    Frenzied Member
    Join Date
    Apr 2016
    Posts
    1,415

    Re: Runtime Item Collection Initialization

    I don't think the Visible property of the listbox directly affect the availability of the items in the listbox..

    But the listbox must be visible on the form in order for it to be able to interact with the data source and populate its Items collection.

    The reason why the listbox items are not available (until added to the form) is because the listbox control DataSource property is not set until the control is added to the form.

    So until the listbox is added to the form, the Items collection is empty ( no data) .

    When the lisbox is added to the form, the DataSource property is set and the items is populated with data from the DataTable...

    I'm not sure how much more technical it can be but let's see what other people say...

  5. #5

    Thread Starter
    Addicted Member
    Join Date
    Jan 2022
    Posts
    211

    Re: Runtime Item Collection Initialization

    because the listbox control DataSource property is not set until the control is added to the form
    If this is correct then it is the answer to the question. If this property is not set at runtime, and instead is in limbo until the control is Visible on the form, would surely be the reason the collection is not initialized. Will run some more tests based on this

  6. #6
    Frenzied Member
    Join Date
    Apr 2016
    Posts
    1,415

    Re: Runtime Item Collection Initialization

    Well I suppose is may be possible to set the ds property before the control is added to the form, but it will not be visible until the control is added to the form...

  7. #7

    Thread Starter
    Addicted Member
    Join Date
    Jan 2022
    Posts
    211

    Re: Runtime Item Collection Initialization

    Quote Originally Posted by schoemr View Post
    Well I suppose is may be possible to set the ds property before the control is added to the form, but it will not be visible until the control is added to the form...
    Im wondering why its not assessable unless it is visible.

  8. #8
    Frenzied Member
    Join Date
    Apr 2016
    Posts
    1,415

    Re: Runtime Item Collection Initialization

    Quote Originally Posted by vbdotnut View Post
    Im wondering why its not assessable unless it is visible.
    Perhaps this is your technical part... Which I don't know 🙂

  9. #9

    Thread Starter
    Addicted Member
    Join Date
    Jan 2022
    Posts
    211

    Re: Runtime Item Collection Initialization

    Perhaps this is your technical part... Which I don't know 🙂
    We are making progress though, 9 posts in and the question is pretty well formed at this point

  10. #10
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,041

    Re: Runtime Item Collection Initialization

    I've certainly never tried this. Still, visibility doesn't seem likely to be the key. Having visibility toggle something other than whether or not the control was rendered to the screen would be a pretty serious mistake, in my opinion. That would be a terrible side effect to have for a simple property.

    What steps did you try? I see the code in the first snippet, which is in the Load event handler. I don't see anything about visibility, though you have two commented lines that suggest that you aren't seeing the listbox being populated until it is added to the controls collection. Is that what you mean by visibility?

    That would be interesting, and I'd have some speculation as why that would be, but it's just speculation. In the old (now defunct) .NET Compact Edition that was used for PDA's, there was no listbox control. That version of the language was stripped to its barest of bones because of the VERY restricted memory on a PDA. They dropped lots of controls, and the listbox was one of those. Still, a listbox was mighty convenient, so I built my own. I did this by putting a panel on the screen with a scrollbar on one side and a whole bunch of labels. I then filled the labels from some underlying list based on the scrollbar value. This looked and acted just like a listbox.

    I mentioned this to a relative of mine, who has been the programming lead for .NET, and he confirmed that what I had done is essentially what a listbox was. It's not a list that extends out of the visible area, it's a series of labels that gets populated from some list based on where the scrollbar is located. How many labels (they aren't REAL labels, but you can think of them that way) are shown depends on the size of the listbox. The larger the listbox, the greater the number of items that can be shown.

    So, how big is the listbox? Well, you set a size and a position for it, but the position is relative to its container. What's displayed depends to some extent on the container, as well. Therefore, I would speculate (without any proof), that the listbox doesn't know how many items it needs to get from the data source until it knows how much it has to render. Perhaps it doesn't even try until it knows how much it has to render. That could be efficient.

    There's a counter argument to that one, though, as the size of the listbox and the value of any scrollbar IS known, even if the listbox isn't shown. Still, when does it get painted? The owner calls paint on the children, so an unowned listbox would never be painted. If the paint is when if figures out what it needs to show, that could explain what you are seeing, perhaps.
    My usual boring signature: Nothing

  11. #11

    Thread Starter
    Addicted Member
    Join Date
    Jan 2022
    Posts
    211

    Re: Runtime Item Collection Initialization

    The only additional steps I have added was add a static panel to the form with its visibility set to false, then added the ListBox to the panel instead of the form, the collection was still not assessable until the Panel was set to Visible

  12. #12
    Frenzied Member
    Join Date
    Apr 2016
    Posts
    1,415

    Re: Runtime Item Collection Initialization

    I did some searching and scanned over the listbox class documentation and I can't see why it's like that..

  13. #13
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,041

    Re: Runtime Item Collection Initialization

    Toggling the Visibility property was enough?

    That would strongly suggest that my theory that it is the painting of the listbox that populates the collection, is correct. Offhand, I can't think of a way to test it further. I don't know that you can disable the paint event for a control.
    My usual boring signature: Nothing

  14. #14

    Thread Starter
    Addicted Member
    Join Date
    Jan 2022
    Posts
    211

    Re: Runtime Item Collection Initialization

    Is there a way to expose the the Classes and whatnot that related to Methods? What exactly is executing within the .Visible method?

  15. #15

    Thread Starter
    Addicted Member
    Join Date
    Jan 2022
    Posts
    211

    Re: Runtime Item Collection Initialization

    it has something to do with the binding methods. If you add items to the list otherwise the collection will have items prior to adding it to the form. Though to accomplish this without binding would require a tricky way to insert the val/string item to maintain the value/value member relationship

    Code:
    Private Sub FormListBox_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim Lbox As New ListBox With {.Name = "ListBox1"}
        For i As Integer = 1 To 10
            Lbox.Items.Add(i.ToString)
        Next
        'Lbox.Items.Count = 10
        Controls.Add(Lbox)
        Stop
        'Lbox.Items.Count = 10
    End Sub
    Last edited by vbdotnut; Jan 24th, 2023 at 02:34 PM.

  16. #16
    Frenzied Member
    Join Date
    Apr 2016
    Posts
    1,415

    Re: Runtime Item Collection Initialization

    Quote Originally Posted by vbdotnut View Post
    it has something to do with the binding methods. If you add items to the list otherwise the collection will have items prior to adding it to the form. Though to accomplish this without binding would require a tricky way to insert the val/string item to maintain the value/value member relationship

    Code:
    Private Sub FormListBox_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim Lbox As New ListBox With {.Name = "ListBox1"}
        For i As Integer = 1 To 10
            Lbox.Items.Add(i.ToString)
        Next
        'Lbox.Items.Count = 10
        Controls.Add(Lbox)
        Stop
        'Lbox.Items.Count = 10
    End Sub
    What exactly is it that you want to do? Your example is not realy demonstrating proper binding methods..

  17. #17
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,041

    Re: Runtime Item Collection Initialization

    Quote Originally Posted by vbdotnut View Post
    Is there a way to expose the the Classes and whatnot that related to Methods? What exactly is executing within the .Visible method?
    Yeah, there is. All that code is available by some means. I haven't explored it, and don't know if it is restricted to some versions of VS, or not, but it is available. It won't be VB, though, it will be C#.
    My usual boring signature: Nothing

  18. #18

    Thread Starter
    Addicted Member
    Join Date
    Jan 2022
    Posts
    211

    Re: Runtime Item Collection Initialization

    What exactly is it that you want to do? Your example is not realy demonstrating proper binding methods..
    the code you have quoted is not demonstrating any binding methods at all, so I have to ask to which methods are you referring to that are not "proper" The first example uses binding, the second does not and simply demonstrates that the collection has items prior to the ListBox being visible when using the .Add method of the ListBox where as the first example that uses binding does not. If you are asking to what application would this be applicable, a good example would be where you have a good deal of listbox controls to add at runtime that you wish to set their item in a default scenario after the the datasource has been set. From this experiment I have learned that either you need create another routine to re-iterate the ListBox's, deal with the choppy control drawing, or use the .Items.Add method during initial iteration and sort a way to add the Value/Display member from the intended datatable rows in the same manner(effect) as the databinding will accomplish.
    Last edited by vbdotnut; Jan 24th, 2023 at 06:01 PM.

  19. #19

    Thread Starter
    Addicted Member
    Join Date
    Jan 2022
    Posts
    211

    Re: Runtime Item Collection Initialization

    Yeah, there is. All that code is available by some means. I haven't explored it, and don't know if it is restricted to some versions of VS, or not, but it is available. It won't be VB, though, it will be C#.
    Will have to research this further.

  20. #20

    Thread Starter
    Addicted Member
    Join Date
    Jan 2022
    Posts
    211

    Re: Runtime Item Collection Initialization

    As somewhat of a conclusion to this. I have found the Opacity property of the form to be useful in hiding the ugly draw methods on databound ctonrols where you need to work with the item collection during an initialization iteration and after they are visible on the form. (IE where you want to use the SetSelected method of a Listbox during its initialization and after the datasource has been set and there is no collection available until the ListBox is visible on the form).
    Code:
    Using FrmItem As New FormItem(DSet.Tables("item"), ItemParams) With {.Opacity = 0}
        FrmItem.ShowDialog()
    End Using
    
    'This is in the FormItem Class
    Using WaitForm As New Form
        Dim WaitMsg As New Label With {
            .Text = "Doing stuff"}
        WaitForm.Controls.Add(WaitMsg)
        WaitForm.Show()
    
        'Do all the UI work...
        Opacity = 100
    End Using
    -Edit:

    Curiously the label added to the wait form shows as more of a place holder instead of text, like you can tell its on the form but its not drawn in full. even if you create a form in designer and add a static label instead of creating the form at runtime the result is the same. Its like the UI is just stuck on stoopid until all of the controls are added. The wait form needs to be Initialized in Sub New
    Code:
    Public Class FormItem  
        Dim FrmWait As Form
    
    Public Sub New(ByVal _DT As DataTable, ByVal _ItemParams As String())
        InitializeComponent()
       
    
        FrmWait = New Form With {.Name = "WaitForm", .Width = 300, .Height = 200, .StartPosition = FormStartPosition.CenterScreen}
        With FrmWait
            .Controls.Add(New Label With {.Text = "Please Wait"})
        End With
        FrmWait.Show()
    
    End Sub
    But now when I close FrmWait at the end of the UI routine, so too does FormItem close or hide. So weird...
    Last edited by vbdotnut; Jan 25th, 2023 at 07:55 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width