I found an old article on CodeProject about FlowLayoutPanel, but that code cannot work on CF because CF Panel does not have OnLayout event. Also the code logic has bugs too.
After searching for a while, I decided to make a FlowLayoutPanel for CF by myself. It turns out the code is not hard to write:
Protected Overloads Overrides Sub OnPaint(ByVal pEvent As PaintEventArgs) Dim nextTop As Integer = 0, nextLeft As Integer = 0 Dim maxHeight As Integer = 0 Dim ParentWidth As Integer If Me.Parent IsNot Nothing Then ParentWidth = Me.Parent.Width Else ParentWidth = Me.Width End If ' Modify control location for the layout For Each myControl As Control In Me.Controls ' Ignore invisible controls If myControl.Visible = False Then Continue For End If If (nextLeft + myControl.Width) > ParentWidth Then nextTop += maxHeight nextLeft = 0 ' Reset maxHeight maxHeight = 0 End If myControl.Top = nextTop myControl.Left = nextLeft If myControl.Height > maxHeight Then maxHeight = myControl.Height End If nextLeft += myControl.Width Next Me.AutoScrollPosition = New System.Drawing.Point(0, 0) MyBase.OnPaint(pEvent) End Sub
Below is a sample using the logic above:
To make layout easier, I put several panels inside the FlowLayoutPanel. You can see all the controls are arranged properly. When I click the "Hide Panel 3" button, the Form becomes this:
The controls below Panel 3 are moved up automatically. If I click "Show Panel 3" button, the Panel 3 will be displayed at original place and all the controls below it are moved down accordingly.
The code for the button is like below:
Private Sub btnHide_Click(ByVal sender As Object, ByVal e As EventArgs) If btnHide.Text = "Hide Panel 3" Then Panel3.Visible = False btnHide.Text = "Show Panel 3" Else Panel3.Visible = True btnHide.Text = "Hide Panel 3" End If ' Refresh the flow layout panel Me.FlowLayoutPanel1.Invalidate() End Sub
There is a small problem in Visual Studio though: when you drag-drop a control to the FlowLayoutPanel, Visual Studio always puts the control as the first one inside the FlowLayoutPanel. You need to modify the designer file to manually put those controls in order:
'FlowLayoutPanel1
'
Me.FlowLayoutPanel1.Controls.Add(Me.Panel1)
Me.FlowLayoutPanel1.Controls.Add(Me.Panel2)
Me.FlowLayoutPanel1.Controls.Add(Me.Panel3)
Me.FlowLayoutPanel1.Controls.Add(Me.Panel5)
Me.FlowLayoutPanel1.Controls.Add(Me.Panel6)
Me.FlowLayoutPanel1.Controls.Add(Me.Panel4)
2 comments:
Very nice idea to get a flowlayout. I was looking for soemthing like javas awt flow control and stumbled into your post.
Many thanks for sharing this.
see my website hjgode.de/wp
josef
I just stumbled across this now, like 5 months after posting, so I have no idea if this will reach you or not, but I wanted to say thanks for this code. Helped me a lot.
Also, wanted to leave you a tip to make this better, easier to use. If you enumerate through the Controls array, in reverse order it will eliminate the drag issue where the control always goes to the top.
Take Care.
Kevin
Post a Comment