C#:如何交换两个winform控件的位置

时间:2009-09-01 08:56:57

标签: c# winforms collections controls

假设您有两个Control,Alice和Bob,并且您想要交换他们的位置。我的意思是在交换之后:

  • 如果他们住在同一个ControlCollection,那么Alice应该拥有Bob的索引,反之亦然。
  • 如果在不同的ControlCollection中,Alice应该与Bob具有相同的索引,但是在Bobs ControlCollection中,反之亦然。

你会怎么做?由于ControlCollection方法的工作方式,我有点不确定如何最好地解决这个问题。例如,使用Remove方法删除控件将更改集合中后面的所有控件的索引。 SetChildIndex以类似的方式工作。

编辑: Alice和Bob的父控件是流布局面板。这就是为什么我要交换它们的索引,这将有效地在流程布局面板中交换它们的位置。

5 个答案:

答案 0 :(得分:6)

对于两个控件位于同一FlowLayoutPanel的简单情况,请使用Controls上的SetChildIndex方法。

像这样......

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

注意:我没有正确处理序列 - 你需要先将前一个控件放到位,否则当第二个控件移到它之前时,结果索引会过高。但这对读者来说是一种练习。

对于更复杂的情况,控件位于不同的FlowLayoutPanel上,代码更简单(序列无关紧要)并且更复杂(需要从一个面板中删除每个控件并添加到另一个)。

答案 1 :(得分:1)

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);

可能不是最短路,但它应该有用......

答案 2 :(得分:0)

我认为你无法完全按照自己的目标去做。但是你的要求对我来说似乎很奇怪:你可以完美地在视觉上交换表单中的两个控件,而不会对其父级ControlCollection中的各自索引有任何限制。

您最接近的是将控件存储在Panel

  • 您有PanelAPanelB
  • 首先,PanelA将包含AlicePanelB将包含Bob
  • 交换时,将Bob存储到PanelA,将Alice存储到PanelB

AliceBob不会直接出现在ControlCollection中,只有Panel会出现。

答案 3 :(得分:0)

在调查这个问题时,我发现了一些东西。 我发现Control.BringToFront()实际上改变了ControlCollection中的位置。

所以:

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

将颠倒ControlCollection中的顺序。

答案 4 :(得分:-1)

我要说你必须从你正在使用的ControlCollection中删除所有控件并将它们存储到一个尊重元素顺序的数据结构中(可能是{{1} }}?)。

在第一种情况下,您可以在SortedList 中交换Alice和Bob ,然后将SortedList中的所有控件重新添加回{{ 1}}。

第二种情况与第一种情况相似,只是你有2只SortedList,你可以在它们之间交换Alice和Bob。