vb.netflowlayoutpanel

In VB.Net one FlowLayoutPanel is not showing any controls


I have a form with a TabControl that has 6 TabPages. Each TabPage has a FlowLayoutPanel that I add custom controls and labels to at runtime. One page isn't showing any controls and I can't figure out why. Each panel is loaded the same way with Dock:Fill, FlowDirection:TopDown and WrapContents:False

I do limit the custom controls to 25 per tab, trying to fill them all at once didn't display right and would probably take more resources than my pc has.

Earlier it was the first tab, but after the control count got over 10 or so it corrected itself. Now it's the third tab. I've tried a number of things to narrow down the problem.

  1. The panel is not empty, the code works as intended
  2. I added a button to programmatically add more labels to see if it would correct itself with more controls. It didn't help.
  3. I altered the button to change the dock, visibility, flow direction, wrap and a few other random attributes I found... The only one that changed anything was setting the flow direction to left-right. This shows the controls, but they flow off the right side of the panel with no horizontal scroll bar. This isn't what I wanted, but might help narrow things down.
  4. I added a big button in design. At first this did nothing, but after I commented off the clear line the controls show up, but only to the width of the button, not the width I set for the controls to fill the panel width.

Visual Studio Community 2019 Windows Forms Application Target Framework: .Net Framework 4 Windows 10

Strange Behavior

flpLowStock.Controls.Clear()
flpLowStock.SuspendLayout()

            'Make all new controls the same width (Fill the width and leave room for the scroll bar)
            Dim intWidths As Integer = flpLowStock.Width - 23

            'Add controls to Low Stock panel from filters
            intCurCtrlCount = 0
            For Each ucLSItm As ucBStockRepItem In lsLowStockItems
                'Does Current Item Match our Filters?
                Dim bInclude As Boolean = True
                If strFilteredDept <> "" AndAlso strFilteredDept <> ucLSItm.BackstockItem.Department Then
                    bInclude = False
                ElseIf strFilteredCat <> "" AndAlso strFilteredCat <> ucLSItm.BackstockItem.Category Then
                    bInclude = False
                ElseIf strFilteredDT <> "" AndAlso strFilteredDT <> ucLSItm.BackstockItem.DisplayAction Then
                    bInclude = False
                ElseIf strFilteredStyle <> "" AndAlso ucLSItm.BackstockItem.StyleNumber.Contains(strFilteredStyle) = False Then
                    bInclude = False
                End If

                If bInclude Then
                    'Make sure we're not over the limit
                    If intCurCtrlCount <= intItemLimit Then
                        'Move to Backstock
                        If lsLSHeaders.Contains(ucLSItm.BackstockItem.DisplayAction) = False Then
                            'Check Action Header
                            Dim lblNewAction As New Label With {
                                .Name = "lblHeader" & intCurLabel,
                                .Text = ucLSItm.BackstockItem.DisplayAction,
                                .BackColor = Color.Silver,
                                .ForeColor = dicActions(ucLSItm.BackstockItem.DisplayAction),
                                .AutoSize = False,
                                .Width = intWidths,
                                .Height = 23
                            }
                            intCurLabel += 1
                            flpLowStock.Controls.Add(lblNewAction)
                            'Uptdate Anchor AFTER it's added to the panel
                            lblNewAction.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right

                            lsLSHeaders.Add(ucLSItm.BackstockItem.DisplayAction)
                        End If
                        If lsLSHeaders.Contains(ucLSItm.BackstockItem.Department) = False Then
                            'Check Department Header
                            Dim lblNewDept As New Label With {
                                .Name = "lblHeader" & intCurLabel,
                                .Text = ucLSItm.BackstockItem.Department,
                                .BackColor = Color.Green,
                                .AutoSize = False,
                                .Width = intWidths,
                                .Height = 23
                            }
                            intCurLabel += 1
                            flpLowStock.Controls.Add(lblNewDept)
                            'Uptdate Anchor AFTER it's added to the panel
                            lblNewDept.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right

                            lsLSHeaders.Add(ucLSItm.BackstockItem.Department)
                        End If
                        If lsLSHeaders.Contains(ucLSItm.BackstockItem.Category) = False Then
                            'Check Category Header
                            Dim lblNewCat As New Label With {
                                .Name = "lblHeader" & intCurLabel,
                                .Text = ucLSItm.BackstockItem.Category,
                                .BackColor = Color.LightSkyBlue,
                                .AutoSize = False,
                                .Width = intWidths,
                                .Height = 23
                            }
                            intCurLabel += 1
                            flpLowStock.Controls.Add(lblNewCat)
                            'Uptdate Anchor AFTER it's added to the panel
                            lblNewCat.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right

                            lsLSHeaders.Add(ucLSItm.BackstockItem.Category)
                        End If
                        'Add the control
                        ucLSItm.Width = intWidths
                        flpLowStock.Controls.Add(ucLSItm)
                        'Uptdate Anchor AFTER it's added to the panel
                        ucLSItm.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right
                    End If

                    intCurCtrlCount += 1
                End If
            Next

            If lsLowStockItems.Count > intItemLimit Then
                Dim lblLOver As New Label With {
                    .Name = "lblLOver",
                    .Text = "Update some items and I'll show you more.",
                    .BackColor = Color.LightCoral,
                    .AutoSize = False,
                    .Width = intWidths,
                    .Height = 23
                }
                flpLowStock.Controls.Add(lblLOver)
            End If


flpLowStock.ResumeLayout(False)
'Fix the layout and show the scrollbar
flpLowStock.PerformLayout()

Solution

  • I decided to see what would happen if I put a static label at the top of each FlowLayoutPanel to possibly fix the width. I discovered while adding this label that if I set autosize to false and the anchor to left, top and right the width automatically goes to zero... Since all of my labels and controls are added with this same anchor the Panel is essentially zero width. This fixes itself when the count goes over 25 because I forgot to add the anchor changes to the buffer label at the bottom...

    So the current fix is to have my first control in the FlowLayoutPanel to be a full width label 2px high and a colored background that has the default top-left anchor and make sure whenever I "clear" the panel I leave that top control alone. Apparently there is no built-in way to allow the contents of the FlowLayoutPanel to resize with the form since anchor doesn't work that way in this case.