Reputation: 1810
I have a need to swap controls in a TableLayoutPanel. They are in separate rows. I've tried the suggested code but to no avail. Is there a solution this other than removing all the controls and re adding? The answer can be in C# or VB.
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
Dim c1 As Control = Me.tlp.GetControlFromPosition(0, 0)
Dim c2 As Control = Me.tlp.GetControlFromPosition(0, 1)
If c1 IsNot Nothing And c2 IsNot Nothing Then
Me.tlp.SetRow(c2, 0)
Me.tlp.SetRow(c1, 1)
End If
End Sub
Upvotes: 6
Views: 3257
Reputation: 1
Same in C# code: swapping / exchanging controls at any positions 1 and 2:
private void SwapControls(TableLayoutPanel tlp, TableLayoutPanelCellPosition cpos1, TableLayoutPanelCellPosition cpos2)
{
var ctl1 = tlp.GetControlFromPosition(cpos1.Column, cpos1.Row);
var ctl2 = tlp.GetControlFromPosition(cpos2.Column, cpos2.Row);
if (ctl1 != null) // position1 can be empty
tlp.SetCellPosition(ctl1, cpos2);
if (ctl2 != null) // position2 can be empty
tlp.SetCellPosition(ctl2, cpos1);
}
Sample of usage:
SwapControls(TableLayoutPanel1, new TableLayoutPanelCellPosition(0, 0), new TableLayoutPanelCellPosition(1, 0))
Upvotes: 0
Reputation: 1810
After searching around for a day and not coming up with nothing I finally took a shot in the dark and found the answer. You need to use the SetChildIndex of the control in the table. See Below...
Note: this only works if you add controls to TableLayoutPanel without row or column index.
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
tlp.RowStyles.Clear()
For i As Integer = 0 To 4
Dim txt As New TextBox
txt.Text = i
txt.Name = "txt" & i
tlp.Controls.Add(txt) 'this works
'tlp.Controls.Add(txt, 0, i) 'this will not work when button is clicked
Next
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
Dim c1 As Control = Me.tlp.GetControlFromPosition(0, 0)
Dim c2 As Control = Me.tlp.GetControlFromPosition(0, 1)
If c1 IsNot Nothing And c2 IsNot Nothing Then
tlp.Controls.SetChildIndex(c1, 1)
tlp.Controls.SetChildIndex(c2, 0)
End If
End Sub
Upvotes: -1
Reputation: 1613
If you have fixed length TableLayoutPanel
, you may use FlowLayoutPanel
(then length of it controls must have equal FlowLayoutPanel
length):
Dim c1 As Control = Button1
Dim c2 As Control = CheckBox1
Dim i1 = FlowLayoutPanel1.Controls.IndexOf(c1)
Dim i2 = FlowLayoutPanel1.Controls.IndexOf(c2)
FlowLayoutPanel1.Controls.SetChildIndex(c1, i2)
FlowLayoutPanel1.Controls.SetChildIndex(c2, i1)
Upvotes: 0
Reputation: 26454
Here is the code to swap controls in a TableLayoutPanel
- you have two options.
1) Swap by reference to controls:
Private Sub SwapControls(tlp As TableLayoutPanel, ctl1 As Control, ctl2 As Control)
Dim ctl1pos As TableLayoutPanelCellPosition = tlp.GetPositionFromControl(ctl1)
tlp.SetCellPosition(ctl1, tlp.GetPositionFromControl(ctl2))
tlp.SetCellPosition(ctl2, ctl1pos)
End Sub
It does not depend on where controls are located in TableLayoutPanel
- could be different rows, columns or both.
Sample usage:
SwapControls(TableLayoutPanel1, Button1, Button2)
2) Swap by column/row index:
Private Sub SwapControls(tlp As TableLayoutPanel, pos1 As TableLayoutPanelCellPosition, pos2 As TableLayoutPanelCellPosition)
Dim ctl1 As Control = tlp.GetControlFromPosition(pos1.Column, pos1.Row)
Dim ctl2 As Control = tlp.GetControlFromPosition(pos2.Column, pos2.Row)
SwapControls(tlp, ctl1, ctl2)
End Sub
Sample usage:
SwapControls(TableLayoutPanel1, New TableLayoutPanelCellPosition(0, 0), New TableLayoutPanelCellPosition(1, 0))
Solutions are based around TableLayoutPanel.SetRow help article on MSDN and some research on its decompiled representation. Both were tested and deemed working.
Upvotes: 6