2009-09-01 34 views
5

假設你有兩個Control s,Alice和Bob,並且你想交換他們的位置。我的意思是交換後:C#:如何交換兩個winform控件的位置

  • 如果他們住在相同的ControlCollection,Alice應該有Bob的索引,反之亦然。
  • 如果在不同的ControlCollection s中,Alice應該與Bob有相同的索引,但是在Bobs ControlCollection中,反之亦然。

你會怎麼做?由於ControlCollection方法的工作原理,我不確定如何最好地解決這個問題。例如,使用Remove方法刪除控件將更改集合中所有控件的索引。 SetChildIndex以類似的方式工作。

編輯: Alice和Bob的父控件是流佈局面板。這就是爲什麼我想交換它們的索引,它實際上將在流佈局面板中交換它們的位置。

回答

6

對於簡單的情況,其中兩個控制都在同FlowLayoutPanel,使用上ControlsSetChildIndex方法。

事情是這樣的......

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

注:我還沒有處理順序這裏正確 - 你需要首先把前面的控制到位,否則當第二移動提前吧,結果指數會過高。但這是對讀者的練習。

對於更復雜的情況,其中控件位於不同的FlowLayoutPanel s,代碼更簡單(順序無關緊要)並且更復雜(每個控件需要從一個面板中刪除並添加到另一個面板中)。

0

我不認爲你可以做到你正在努力實現的目標。但是你的要求對我來說似乎很陌生:你可以在表單中完全直觀地交換表單中的兩個控件,而不受任何父母的ControlCollection中各自索引的約束。

你可以得到最接近的將是存儲在您的Panel控制:

  • 你必須PanelAPanelB
  • 起初,PanelA將包含AlicePanelB將包含Bob
  • 交換時,將Bob存儲到PanelAAlice存儲爲PanelB

AliceBob不會在ControlCollection直接出現雖然只有Panel s就。

+0

對不起,應該說他們所在的面板是流動佈局面板。所以這就是爲什麼我需要交換他們的索引來交換他們的視覺位置。編輯我的問題=) – Svish 2009-09-01 09:41:08

-1

我想說,你必須從你正在使用的ControlCollection(s)中刪除所有控件,並將它們存儲到一個尊重元素順序的數據結構中(可能是SortedList?)。

在第一種情況下,你會然後交換Alice和Bob SortedList,然後從SortedList重新添加所有控件回ControlCollection

第二種情況與第一種情況類似,只是您有2 SortedList s,您可以在它們之間交換Alice和Bob。

+1

每個容器控件上存在的'Controls'屬性不是一個簡單的列表 - 它本身就是一個單獨的對象(Control.ControlCollection - http://msdn.microsoft.com/en-us/ library/system.windows.forms.control.controlcollection(VS.71).aspx),它提供了對移動事物的直接支持。如果您按照您的建議移除並重新添加所有控件,界面會閃爍一些可怕的東西 - 而且代碼會變慢**。 – Bevan 2009-09-01 10:00:27

+0

同意,但它會解決他的問題。我忘記了可以用yopu回答的方式使用'SetChildIndex',所以非常感謝。 :) – 2009-09-01 10:21:36

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

可能不是最短的路,但它應該工作...

0

當我研究這個問題時,我將其標記爲某物。 我發現Control.BringToFront()實際上改變了ControlCollection中的位置。

所以:

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

將扭轉在ControlCollection的順序。