2011-03-22 6 views
31

¿es posible hacer que los elementos insertados en FlowLayoutPanel sean del tamaño automático del FlowLayoutPanel? Aquí está un ejemplo:FlowLayoutPanel - Ancho automático para los controles?

Un formulario con 1 FlowLayoutPanel y 3 botones dentro:

enter image description here

si cambio el tamaño de la forma, los controles de tener este aspecto: que organizar "izquierda a derecha"

enter image description here

lo que yo quiero es éste: los controles deben tener el ancho de la FlowLayoutPanel:

enter image description here

¿Alguna idea de cómo hacer esto? Cambié el FlowDirection y jugué con la propiedad Anchor pero sin suerte.

Podría, por supuesto, cambiar el tamaño de los controles en el evento FlowLayoutPanel_Resize, pero quiero agregar aproximadamente 500 controles de usuario - Lo probé y es lento.

+3

Sí, cambio de tamaño funciona bien. Lo que sea que haga, no * * agregue 500 controles, succionará lodo serio. Un formulario no debe tener más de 50 controles. –

+0

Estoy intentando crear algún tipo de "ListView" como el de Apple Automator: http://bit.ly/fxkMaH – MilMike

+0

Solo veo 4 elementos en el enlace que proporcionó, no 500. – Justin

Respuesta

27

Le sugiero que use TableLayoutPanel con una columna en este caso. He encontrado que TableLayoutPanel es mucho más predecible y sólido que FlowLayoutPanel.

Otra opción, si todavía quiere usar FlowLayoutPanel, es establecer el primer ancho de control al deseado, y usar Dock = Top para todos los demás controles.

+1

Pero luego, cada vez que agrega un control, debe administrar el número de filas de la tabla, ¿verdad? – J4N

2

Sugiero ... intentar jugar con los anclajes de los botones ... tratar de establecerla como

Button1.Anchor = (AnchoreStyle.Left or AnchoreStyle.Right) 

o establecido en las propiedades ...

y luego ponerlo en el interior un Panel en lugar de FlowLayoutPanel ...;)

+0

De acuerdo. Sin embargo, el Panel no maneja el margen de Controles secundarios correctamente. – Larry

13

Es una forma simple de hacer esto. Solo enlaza el evento SizeChanged de tu flowLayoutPannel y cambia el tamaño del control que lo contiene. térmica:

private void myFlowLayoutPannel_SizeChanged(object sender, EventArgs e) 
{ 
    myFlowLayoutPannel.SuspendLayout(); 
    foreach (Control ctrl in pnSMS.Controls) 
    { 
     if (ctrl is Button) ctrl.Width = pnSMS.ClientSize.Width; 
    } 
    myFlowLayoutPannel.ResumeLayout(); 
} 
+0

Este también fue mi primer pensamiento al encontrarme con este problema, pero ¿no podría esto ralentizar la GUI? – Traubenfuchs

+0

Súper hombre, está funcionando bien para mí. Mezclo la solución anterior con esta :) – Amir

+1

Demasiado viejo, pero sugeriría utilizar el evento 'Layout' de' FlowLayoutPannel' para cambiar el tamaño de los controles. – bansi

2

El FlowLayoutPanel organiza los controles de una manera particular, de acuerdo con MSDN:

... para las direcciones de flujo vertical, el control FlowLayoutPanel calcula la anchura de una columna implícita de el control infantil más amplio en la columna . Todos los demás controles de esta columna con Ancla o Base se alinean o estiran para adaptarse a esta columna implícita. El comportamiento funciona de manera similar para direcciones de flujo horizontal.

No es ideal, pero se puede hacer esto de forma nativa, siempre y cuando un control está puesto a la misma anchura que el contenedor, y el resto de los controles se establecen para Dock.

2

aquí tengo mi clase StackPanel:

/// <summary> 
/// A stackpanel similar to the Wpf stackpanel. 
/// </summary> 
public class StackPanel: FlowLayoutPanel 
{ 
    public StackPanel(): base() 
    { 
     InitializeComponent(); 
     this.ForceAutoresizeOfControls = true; 
    } 

    private void InitializeComponent() 
    { 
     this.SuspendLayout(); 
     // 
     // StackPanel 
     // 
     this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 
     this.WrapContents = false; 
     this.ResumeLayout(false); 
    } 

    /// <summary> 
    /// Override it just in order to hide it in design mode. 
    /// </summary> 
    [Browsable(false)] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    public new bool WrapContents 
    { 
     get { return base.WrapContents; } 
     set { base.WrapContents = value; } 
    } 

    /// <summary> 
    /// Override it just in order to set its default value. 
    /// </summary> 
    [DefaultValue(typeof(AutoSizeMode), "GrowAndShrink")] 
    public override AutoSizeMode AutoSizeMode 
    { 
     get { return base.AutoSizeMode; } 
     set { base.AutoSizeMode = value; } 
    } 

    /// <summary> 
    /// Get or set a value that when is true forces the resizing of each control. 
    /// If this value is false then only control that have AutoSize == true will be resized to 
    /// fit the client size of this container. 
    /// </summary> 
    [DefaultValue(true)] 
    public bool ForceAutoresizeOfControls { get; set; } 

    protected override void OnSizeChanged(EventArgs e) 
    { 
     base.OnSizeChanged(e); 
     this.SuspendLayout(); 
     switch (FlowDirection) 
     { 
      case FlowDirection.BottomUp: 
      case FlowDirection.TopDown: 
       foreach (Control control in this.Controls) 
        if (ForceAutoresizeOfControls || control.AutoSize) 
         control.Width = this.ClientSize.Width - control.Margin.Left - control.Margin.Right; 
       break; 
      case FlowDirection.LeftToRight: 
      case FlowDirection.RightToLeft: 
       foreach (Control control in this.Controls) 
        if (ForceAutoresizeOfControls || control.AutoSize) 
         control.Height = this.ClientSize.Height - control.Margin.Top - control.Margin.Bottom; 
       break; 
      default: 
       break; 
     } 
     this.ResumeLayout(); 
    } 

    protected override void OnLayout(LayoutEventArgs levent) 
    { 
     base.OnLayout(levent); 

     if (levent != null && levent.AffectedControl != null) 
     { 
      Control control = levent.AffectedControl; 
      if (ForceAutoresizeOfControls || control.AutoSize) 
      { 
       switch (FlowDirection) 
       { 
        case FlowDirection.BottomUp: 
        case FlowDirection.TopDown: 
         control.Width = this.ClientSize.Width - control.Margin.Left - control.Margin.Right; 
         break; 
        case FlowDirection.LeftToRight: 
        case FlowDirection.RightToLeft: 
         control.Height = this.ClientSize.Height - control.Margin.Top - control.Margin.Bottom; 
         break; 
        default: 
         break; 
       } 
      } 
     } 
    } 
} 
Cuestiones relacionadas