Question

Est-il possible de rendre les éléments insérés dans FlowLayoutPanel la taille automatique du FlowLayoutPanel?Voici un exemple:

Un formulaire avec 1 FlowLayoutPanel et 3 boutons à l'intérieur:

entrez la description de l'image ici

si je redimensionne le formulaire, les contrôles ressemblent à ceci: ils organisent "de gauche à droite"

entrez la description de l'image ici

Ce que je veux, c'est ceci: Les contrôles doivent avoir la largeur du FlowLayoutPanel:

entrez la description de l'image ici

Des idées comment faire cela?J'ai changé le FlowDirection et joué avec la propriété Anchor mais sans chance.

Je pourrais bien sûr redimensionner les contrôles dans l'événement FlowLayoutPanel_Resize, mais je veux ajouter environ 500 contrôles utilisateur - je l'ai testé et c'est lent.

Était-ce utile?

La solution

Je vous suggère d'utiliser TableLayoutPanel avec une colonne dans ce cas.J'ai trouvé TableLayoutPanel beaucoup plus prévisible et solide que FlowLayoutPanel.

Une autre option, si vous souhaitez toujours utiliser FlowLayoutPanel, consiste à définir la largeur du premier contrôle sur celle souhaitée et à utiliser Dock= Top pour tous les autres contrôles.

Autres conseils

C'est un moyen simple de le faire. Liez simplement l'événement SizeChanged de votre flowLayoutPannel et redimensionnez le contrôle contenant. Comme:

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

ici, j'ai ma classe 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;
                }
            }
        }
    }
}

Le FlowLayoutPanel organise les contrôles d'une manière particulière, selon MSDN :

... pour les directions d'écoulement verticales, le contrôle FlowLayoutPanel calcule la largeur d'une colonne implicite à partir du contrôle enfant le plus large du colonne .Toutes les autres commandes de cette colonne avec Anchor ou Dock les propriétés sont alignées ou étirées pour s'adapter à cette colonne implicite.La Le comportement fonctionne de la même manière pour les directions d'écoulement horizontales.

Ce n'est pas idéal, mais vous pouvez le faire de manière native, à condition qu'un contrôle enfant soit défini sur la même largeur que le conteneur et que le reste des contrôles soit défini sur Dock.

Je suggère ... essayez de jouer avec les ancres des boutons ... essayez de le définir comme

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

ou définissez-le dans les propriétés ...

puis placez-le dans un Panel au lieu du FlowLayoutPanel ...;)

Vous devriez pouvoir faire ce que vous voulez avec un contrôle FlowLayoutPanel normal. Ancrez-le sur les quatre côtés pour qu'il s'étire avec votre formulaire, puis ajoutez vos boutons et définissez-les tous sur Dock: Top.

Travail terminé.

Comme d'autres réponses l'ont indiqué, le Panel lui-même est suffisant pour gérer vos boutons.Un peu de code qui fonctionne pour moi:

public class ButtonWindow : Panel
{
    public ButtonWindow()
    {
        Dock = DockStyle.Fill;
        AutoScroll = true;

        for (int i = 0; i < 500; i++) 
        {
           Button button = new Button() { Height = 100, Dock = DockStyle.Top };
           Controls.Add(button);
        }
    }
}

Passez une bonne journée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top