2008-11-11 27 views
5

Tengo un problema peculiar con el orden en el que se agregan los paneles FlowLayout en la propiedad del control. Esto es lo que probé,Orden de controles en la propiedad de control de un formulario en C#

Agregué 7 FlowLayoutPanels en una aplicación de ventana C# de izquierda a derecha en tiras verticales. Luego etiqueté los diseños de flujo como 1, 2, 3, ... 7 nuevamente de izquierda a derecha. Ahora en el controlador de carga del formulario, escribí el siguiente fragmento,

foreach (FlowLayoutPanel aDaysControl in this.Controls) 
    { 
     MessageBox.Show(aDaysControl.Tag.ToString()); 
    } 

que esperaba que los mensajes aparezcan en el orden de 1, 2, ... 7. Pero lo obtuve en el orden inverso (7, 6, ... 1). ¿Podría alguien ayudarme con el error que cometí?

La razón detrás de preservar el orden,

estoy tratando de hacer un control de calendario con cada fila representa un día. Si un mes comienza desde el miércoles, entonces I debe agregar una etiqueta vacía a la primera (lunes) y la segunda (martes) fila . Por lo que el orden importa un poco

+0

Comentó en mi respuesta que el pedido era importante para usted. Estoy muy interesado en entender por qué. ¿Podrías editar tu pregunta para explicar el motivo? Gracias. –

Respuesta

3

mirada en el orden en que se agregan a la forma en la yourForm.designer.cs

+0

Sí. Ese es ese problema. Se agregaron de la manera opuesta. No sé por qué. Gracias –

0

¿Es realmente un problema?

Siempre que la UI funcione correctamente (en términos de orden de tabulación, por ejemplo), recomendaría que no haga suposiciones sobre el orden en el que están enumeradas.

EDITAR: Gracias por explicar su requerimiento con más detalle. Creo que aún recomendaría no usar el orden en que están almacenados en la colección Controls. Siempre es mejor considerar estos detalles de implementación como 'opacos'. Tiene una etiqueta asociada a cada control, por lo que puede usar esto para identificar el control correcto. Con el fin de acelerar el proceso, se podría construir una matriz de 7 elementos que hace referencia a los controles por los ordinales:

FlowLayoutPanel[] panels = new FlowLayoutPanel[7]; 

foreach(FlowLayoutPanel panel in this.Controls) 
{ 
    panels[(int)panel.Tag] = panel; 
} 

// Now, you can reference the panels directly by subscript: 

panels[2].BackColor = Color.Aquamarine; 

Aunque me gustaría poner algún tipo de comprobación en que este Código sea un poco más robusto!

+0

¡Pero la orden __sí___ importa en mi caso !! –

1

si nos fijamos en el código generado por el diseñador Form1.designer.cs que se verá algo como esto:

 // 
     // Form1 
     // 
     this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
     this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
     this.ClientSize = new System.Drawing.Size(658, 160); 
     this.Controls.Add(this.flowLayoutPanel7); 
     this.Controls.Add(this.flowLayoutPanel6); 
     this.Controls.Add(this.flowLayoutPanel5); 
     this.Controls.Add(this.flowLayoutPanel4); 
     this.Controls.Add(this.flowLayoutPanel3); 
     this.Controls.Add(this.flowLayoutPanel2); 
     this.Controls.Add(this.flowLayoutPanel1); 
     this.Name = "Form1"; 
     this.Text = "Form1"; 
     this.ResumeLayout(false); 

nota cómo fue construido hasta que agregó panel 1 primero y luego 2, etc., pero a medida que el código se ejecuta, agregará 7 primero, luego 6.

este código estará en la función InitializeComponent() generada por el diseñador.

¿Por qué necesita que se ejecuten en un cierto orden?

yo no confiar en el diseñador de mantener el orden que desee .. me gustaría ordenar los controles de mi ser:

 var flowpanelinOrder = from n in this.Controls.Cast<Control>() 
           where n is FlowLayoutPanel 
           orderby int.Parse(n.Tag.ToString()) 
           select n; 

     /* non linq 
     List<Control> flowpanelinOrder = new List<Control>(); 
     foreach (Control c in this.Controls) 
     { 
      if (c is FlowLayoutPanel) flowpanelinOrder.Add(c);     
     } 
     flowpanelinOrder.Sort(); 
     * */ 

     foreach (FlowLayoutPanel aDaysControl in flowpanelinOrder) 
     { 
      MessageBox.Show(aDaysControl.Tag.ToString()); 
     } 
+0

Estoy tratando de hacer un control de calendario con cada fila que representa un día. Si un mes comienza a partir del miércoles, entonces necesito agregar una etiqueta vacía a la primera (lunes) y la segunda fila (martes). Entonces el orden importa un poco. –

+0

Hmm. Yo era un poco flojo. Aprende la lección ahora –

7

Sé que esto es bastante una vieja pregunta, pero ...

Es posible que desee utilizar SetChildIndex. p.ej. this.Controls.SetChildIndex(button1, 0);

1

¿Qué pasa si en el futuro algún otro diseñador retira los controles, vuelve a agregarse, etc.? Controlar al diseñador siempre es un desastre. Lo que sería mejor es ordenar los controles en el control del contenedor antes de enumerar. Yo uso este método de extensión (si tiene LINQ):

public static List<Control> ToControlsSorted(this Control panel) 
{ 
    var controls = panel.Controls.OfType<Control>().ToList(); 
    controls.Sort((c1, c2) => c1.TabIndex.CompareTo(c2.TabIndex)); 
    return controls; 
} 

y se puede:

foreach (FlowLayoutPanel aDaysControl in this.ToControlsSorted()) 
{ 
    MessageBox.Show(aDaysControl.TabIndex.ToString()); 
} 

(Por encima es para TabIndex). Sería trivial ordenar de acuerdo con Tag.

Cuestiones relacionadas