2009-09-01 28 views
5

Digamos que tiene dos Control s, Alice y Bob, y desea cambiar su posición. Con esto quiero decir que después de la permuta:C#: Cómo cambiar la posición de dos controles winform

  • si viven en la misma ControlCollection, Alice debe tener el índice de Bob y viceversa.
  • Si en ControlCollection s diferente, Alice debe tener el mismo índice que Bob, pero estar en Bobs ControlCollection y viceversa.

¿Cómo harías esto? No estoy seguro de cómo solucionarlo por la forma en que funcionan los métodos ControlCollection. Por ejemplo, usar el método Remove para eliminar un control cambiará el índice de todos los controles que vengan después de él en la colección. SetChildIndex funciona de manera similar.

Editar: Los controles principales de Alice y Bob son paneles de diseño de flujo. Es por eso que quiero cambiar su índice, que de hecho intercambiará su posición en el panel de diseño de flujo.

Respuesta

6

Para el caso simple, donde ambos controles están en la misma FlowLayoutPanel, utilice el método SetChildIndex en Controls.

Algo como esto ...

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

Nota: No he manejado aquí Orden correctamente - que necesita para poner el control anterior en su lugar primero, de lo contrario cuando el segundo se mueve por delante de él, el el índice resultante será uno demasiado alto. Pero eso es un ejercicio para el lector.

Para el caso más complejo, donde los controles están en FlowLayoutPanel s diferentes, el código es más simple (la secuencia no importa tanto) y más complicado (cada control debe eliminarse de un panel y agregarse al otro)

0

No creo que pueda hacer exactamente lo que está tratando de lograr. Pero sus requisitos me parecen extraños: puede intercambiar perfectamente dos controles en un formulario sin ninguna restricción en su índice respectivo en el ControlCollection de su matriz.

Lo más cerca que podría conseguir sería para almacenar sus controles en un Panel:

  • Tendrías PanelA y PanelB.
  • Al principio, PanelA contendría Alice y PanelB contendría Bob.
  • Al intercambiar, almacene Bob en PanelA y Alice en PanelB.

Alice y Bob no aparecería directamente en la ControlCollection sin embargo, sólo los Panel s haría.

+0

Lo siento, debería haber dicho que los paneles en los que se encuentran son paneles de diseño de flujo. Entonces, es por eso que necesito cambiar su índice para cambiar su posición visual. Editado mi pregunta =) – Svish

-1

Yo diría que tiene que quitar todos los controles del ControlCollection (s) con los que está trabajando y almacenarlos en una estructura de datos que respete el orden de los elementos (¿quizás un SortedList?).

En el primer caso, que había entonces intercambiar Alice y Bob en el SortedList y luego volver a agregar todos los controles de la SortedList de nuevo en el ControlCollection.

El segundo caso sería similar al primero, excepto que tendría 2 SortedList s, e intercambiaría Alice y Bob entre ellos.

+1

La propiedad 'Controls' presente en cada control de contenedor no es una lista simple, es un objeto separado por derecho propio (Control.ControlCollection - http://msdn.microsoft.com/en-us/ library/system.windows.forms.control.controlcollection (VS.71) .aspx) y proporciona soporte directo para mover cosas. Si quita y vuelve a agregar todos los controles de la manera que sugiere, la IU parpadeará algo terrible, y el código será ** lento **. – Bevan

+0

De acuerdo, pero resolvería su problema. Olvidé que es posible usar 'SetChildIndex' en la forma que Yopu respondió, así que gracias por eso. :) –

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

el camino más corto, pero debería funcionar ...

0

Me tropecé con algo mientras investigaba este problema. Encontré que el Control.BringToFront() realmente cambia la posición en el ControlCollection.

Así:

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

se invertirá el orden en el ControlCollection.

Cuestiones relacionadas