C #: Как поменять местами два элемента управления winform - PullRequest
5 голосов
/ 01 сентября 2009

Допустим, у вас есть два Control, Алиса и Боб, и вы хотите поменять их позицию. Я имею в виду, что после обмена:

  • Если они живут в одном и том же ControlCollection, Алиса должна иметь индекс Боба и наоборот.
  • Если в разных ControlCollection с, Алиса должна иметь тот же индекс, что и Боб, но быть в Бобсе ControlCollection и наоборот.

Как бы вы это сделали? Я немного не уверен, как лучше решить эту проблему из-за того, как работают методы ControlCollection. Например, использование метода Remove для удаления элемента управления изменит индекс всех элементов управления, следующих за ним в коллекции. SetChildIndex работает аналогичным образом.

Редактировать: Родительские элементы управления Алисы и Боба - это панели макета потока. Вот почему я хочу поменять их индекс, который фактически поменяет их положение на панели макета потока.

Ответы [ 5 ]

6 голосов
/ 01 сентября 2009

Для простого случая, когда оба элемента управления находятся на одном и том же FlowLayoutPanel, используйте метод SetChildIndex для Controls.

Как то так ...

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

Примечание: я не обработал последовательность здесь должным образом - вам нужно сначала поставить более ранний элемент управления на место, иначе, когда второй будет перемещен вперед, результирующий индекс будет слишком большим. Но это упражнение для читателя.

В более сложном случае, когда элементы управления находятся на разных FlowLayoutPanel с, код проще (последовательность не имеет большого значения) и сложнее (каждый элемент управления необходимо удалить с одной панели и добавить в другой).

1 голос
/ 01 сентября 2009
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);

Вероятно, не самый короткий путь, но он должен работать ...

0 голосов
/ 12 октября 2016

Я наткнулся на что-то, глядя на эту проблему. Я обнаружил, что Control.BringToFront() фактически меняет положение в ControlCollection.

Итак:

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

обратит порядок в ControlCollection.

0 голосов
/ 01 сентября 2009

Я бы сказал, что вам нужно удалить все элементы управления из ControlCollection, с которыми вы работаете, и сохранить их в структуре данных, которая учитывает порядок элементов (возможно, SortedList?) .

В первом случае вы должны поменять местами Алису и Боба в SortedList, а затем снова добавить все элементы управления из SortedList обратно в ControlCollection.

Второй случай будет аналогичен первому, за исключением того, что у вас будет 2 SortedList с, и вы поменяете местами Алису и Боба.

0 голосов
/ 01 сентября 2009

Я не думаю, что вы можете сделать именно то, что вы пытаетесь достичь. Но ваши требования кажутся мне странными: вы можете визуально поменять два элемента управления в форме без каких-либо ограничений на их соответствующий индекс в родительском элементе ControlCollection.

Самое близкое, что вы могли бы получить, это сохранить ваши элементы управления в Panel:

  • У вас будет PanelA и PanelB.
  • Сначала PanelA будет содержать Alice, а PanelB будет содержать Bob.
  • При обмене сохраняйте Bob в PanelA и Alice в PanelB.

Alice и Bob не будут отображаться непосредственно в ControlCollection, а только Panel s.

...