Re-Ordering Controls in a FlowLayoutPanel

136 views Asked by At

Evening Everyone,

I've spent a little time trying to figure this one out and I have hit a wall. I am trying to re-order existing UserControls in a FlowLayoutPanel.

Usage... I have a form that contains a FlowLayoutPanel, in that panel, there are multiple UserControls that have their own events and when they have completed their own task, they change the value of the UserControl Tag. Each value is unique and is not repeated (I have verified this by iterating through each control in the panel).

How does one re-order these?

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        FlowLayoutPanel1.SuspendLayout()
        FlowLayoutPanel1.TabStop = True
        Dim p As Integer = 0
        Dim rp As Integer = 0
        For Each r As Control In FlowLayoutPanel1.Controls
            listC(p) = r.Tag
            p += 1
        Next
        For i = 0 To listC.Count
            If listC(i) = 0 Then Exit For
            For Each c As Control In FlowLayoutPanel1.Controls
                If c.Tag = listC(i) Then
                    FlowLayoutPanel1.Controls.SetChildIndex(c, rp)
                    c.TabStop = True
                    c.TabIndex = rp
                    rp += 1
                    Exit For
                End If
            Next
        Next
        FlowLayoutPanel1.ResumeLayout()
        FlowLayoutPanel1.Refresh()
    End Sub
1

There are 1 answers

2
jmcilhinney On

This is off the top of my head but I think that I'd be doing it like this:

Dim children = FlowLayoutPanel1.Controls.
                                Cast(Of Control)().
                                OrderBy(Function(c) CInt(c.Tag)).
                                ToArray()

For i = 0 To children.GetUpperBound(0)
    Dim child = children(i)

    FlowLayoutPanel1.Controls.SetChildIndex(child, i)
Next

Get all the child controls into an array first, sorted by that Tag value, then loop through that array and set the index within the FlowLayoutPanel to the index within the array. You mustn't enumerate a collection and modify that collection at the same time. That's what you're doing here:

For Each c As Control In FlowLayoutPanel1.Controls
    '...
        FlowLayoutPanel1.Controls.SetChildIndex(c, rp)