Svish
Svish

Reputation: 157981

C#: How to swap the position of two winform controls

Let's say you have two Controls, Alice and Bob, and you want to swap their position. By that I mean that after the swap:

How would you do this? I am a bit unsure how to best solve this because of how the ControlCollection methods work. For example using the Remove method to remove a control will change the index of all the controls coming after it in the collection. The SetChildIndex works in a similar way.

Edit: The parent controls of Alice and Bob are flow layout panels. This is why I want to swap their index which will in effect swap their position in the flow layout panel.

Upvotes: 5

Views: 12067

Answers (5)

user1218233
user1218233

Reputation: 1

I stumbeled into something while looking into this problem. I found that the Control.BringToFront() actually changes the position in the ControlCollection.

So:

foreach(Control _control in this.Controls)
  _control.BringToFront()

will reverse the order in the ControlCollection.

Upvotes: 0

Bevan
Bevan

Reputation: 44307

For the simple case, where both controls are on the same FlowLayoutPanel, use the SetChildIndex method on Controls.

Something like this ...

var alphaIndex = panel.Controls.IndexOf(controlAlpha);
var betaIndex = panel.Controls.IndexOf(controlBeta);
panel.Controls.SetChildIndex(controlAlpha, betaIndex);
panel.Controls.SetChildIndex(controlBeta, alphaIndex);

Note: I haven't handled sequence here properly - you need to put the earlier control into place first, else when the second is moved ahead of it, the resulting index will be one too high. But that's an exercise for the reader.

For the more complex case, where the controls are on different FlowLayoutPanels, the code is simpler (sequence doesn't matter so much) and more complicated (each control needs to be removed from one panel and added to the other).

Upvotes: 8

Thomas Levesque
Thomas Levesque

Reputation: 292365

Control bobParent = bob.Parent;
Control aliceParent = alice.Parent;
int bobIndex = bobParent.Controls.GetChildIndex(bob);
int aliceIndex = aliceParent.Controls.GetChildIndex(alice);
bobParent.Controls.Add(alice);
aliceParent.Controls.Add(bob);
bobParent.Controls.SetChildIndex(alice, bobIndex);
aliceParent.Controls.SetChildIndex(bob, aliceIndex);

Probably not the shortest way, but it should work...

Upvotes: 3

Ian Kemp
Ian Kemp

Reputation: 29839

I'd say you have to remove all controls from the ControlCollection(s) you're working with and store them into a data structure(s) that respects the order of elements (maybe a SortedList?).

In the first case, you'd then swap Alice and Bob in the SortedList and then re-add all the controls from the SortedList back into the ControlCollection.

The second case would be similar to the first except that you'd have 2 SortedLists, and you'd swap Alice and Bob between them.

Upvotes: -1

Mac
Mac

Reputation: 8339

I don't think you can do exactly what you are trying to achieve. But your requirements seem strange to me : you can perfectly visually swap two controls in a form without any constraint on their respective index in their parent's ControlCollection.

The closest you could get would be to store your controls in a Panel :

  • You'd have PanelA and PanelB.
  • At first, PanelA would contain Alice and PanelB would contain Bob.
  • When swapping, store Bob into PanelA and Alice into PanelB.

Alice and Bob would not appear directly in the ControlCollection though, only the Panels would.

Upvotes: 0

Related Questions