Click here to Skip to main content
15,910,358 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hello folks:

I have a flow layout panel where users can add buttons. However, while my buttons place themselves nicely on the panel, they are not sorted by name. Here is how the user adds the button:

Private Sub btnAddCategory_Click(sender As Object, e As EventArgs) Handles btnAddCategory.Click

        Dim newButton As New Button

        With newButton

            .Size = CType(New Point(211, 34), Drawing.Size)
            .FlatStyle = Windows.Forms.FlatStyle.Flat
            .FlatAppearance.BorderSize = 0
            .FlatAppearance.BorderColor = System.Drawing.Color.Gray
            .BackColor = System.Drawing.Color.Gray

            .Name = "btn" & TextBox3.Text
            .Text = TextBox3.Text

        End With

        pnlCategories.Controls.Add(newButton)
    


    End Sub


But my buttons are not sorted. So I thought of doing the following to sort my buttons:

Private Sub pnlCategories_ControlAdded(sender As Object, e As ControlEventArgs) Handles pnlCategories.ControlAdded

        For Each btn As Button In Me.Controls.OfType(Of Button)() _
                               .OrderBy(Function(b) b.Text)

        Next

    End Sub


But nothing happens, I know is possible to sort the buttons, but I can't seem to get it to work.
Posted

As far as i know, when controls are added to FlowLayoutPanel, they are "sorted" in the order of addition.

I'd suggest to use List<T>[^] generic class to manage controls. It contains several properties and methods which enables you to sort elements, add, check if exists, clear, etc.

Implementation:
1) Before you add control to FlowLayoutPanel,
    a) check if it exists in the collection,
    b) if not exists - add it to List<T>
    c) sort elements
2) Remove controls from FlowLayoutPanel
3) Add controls to FlowLayoutPanel from List<T>

Maybe it's not elegant solution, but at this moment i have no better idea.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 3-Apr-14 15:24pm    
Well... it would be redundant, and perhaps it does not really explain what to do. OP already does sorting. The problem is different: not reordering the controls is not applied to the panel. The problem is not specific to panel classes. So, there is no need to use the list: a suitable collection already exist and is obtained by the user. Please see my answer.
—SA
This is because you are not doing anything to sort the children. The method OrderBy does no have any side effects. It returns a collection of reordered object. You need to do one more step: remove all controls from its parent and populate them again, this time, in the order you got in the object returned as the result of the ordering.

Besides, the use of OfType is questionable. It's clear what to do if all the children are buttons, but in this case, you should use all the controls, not just buttons. If some of the control are not buttons, you can use some other sorting criteria.

To populate controls, use the property System.Windows.Forms.Control.Controls and the method System.Windows.Forms.Control.ControlCollection.Add:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.controls%28v=vs.110%29.aspx[^],
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.controlcollection.add(v=vs.110).aspx[^],
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.controlcollection.addrange%28v=vs.110%29.aspx[^].

—SA
 
Share this answer
 
Comments
Maciej Los 3-Apr-14 15:33pm    
Ok, your proposal says almost the same what i said. But i understand your intentions.
Sergey Alexandrovich Kryukov 3-Apr-14 15:38pm    
Yes, but the difference is: you suggest to add one more collection. I simply say that this collection is not needed.
—SA
Maciej Los 3-Apr-14 15:43pm    
Wait a moment. I don't get it. Are you saying that Form.FlowLayoutPanel.Controls is the collection which OP needs to manage? I'm bit tired today and my brain is going crazy ;)
Sergey Alexandrovich Kryukov 3-Apr-14 15:48pm    
If you read my answer slower, you'll get it. I don't know what do you mean by "manage". No.
OP calls "OrderBy" in LINQ. This LINQ returns some collection of ordered controls. This is just the calculation, without any side effect. But the collection needed for population already exists. OP does not do anything to the panel itself.
—SA
Maciej Los 3-Apr-14 16:00pm    
My "manage" means your "populate" ;) Manage => add, sort, delete controls from FlowLayoutPanel. I agree, Linq does not do affects on control's position on the Panel (i hope it is correctly spelled and you can understand what i mean). That's why i suggest to use List<t> generic class.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900