Подтвердить что ты не робот

FlowLayoutPanel - автоматическая ширина для элементов управления?

Можно ли сделать вставленные элементы в автоматическом размере FlowLayoutPanel FlowLayoutPanel? Вот пример:

Форма с 1 FlowLayoutPanel и 3 кнопками внутри:

enter image description here

Если я изменил размер формы, элементы управления выглядят так: они упорядочивают "слева направо"

enter image description here

Что я хочу, так это: Элементы управления должны иметь ширину FlowLayoutPanel:

enter image description here

Любые идеи, как это сделать? Я изменил FlowDirection и играл с свойством Anchor, но не повезло.

Я мог бы, конечно, изменить размер элементов управления в событии FlowLayoutPanel_Resize, но я хочу добавить около 500 пользовательских элементов управления - я протестировал его, и он медленный.

4b9b3361

Ответ 1

Я предлагаю вам использовать TableLayoutPanel с одним столбцом в этом случае. Я нашел TableLayoutPanel гораздо более предсказуемым и надежным, чем FlowLayoutPanel.

Другим вариантом, если вы все еще хотите использовать FlowLayoutPanel, является установка первой ширины управления на желаемую, и используйте Dock = Top для всех остальных элементов управления.

Ответ 2

Это простой способ сделать это. Просто привяжите элемент SizeChanged, который вы используете flowLayoutPannel, и измените размер содержащего элемента управления. Как:

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

Ответ 3

здесь у меня есть класс 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;
                }
            }
        }
    }
}

Ответ 4

Я предлагаю... попробуйте сыграть с якорями кнопок... попробуйте установить его как

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

или установите его в свойствах...

а затем поместите его внутри панели вместо FlowLayoutPanel...;)

Ответ 5

FlowLayoutPanel упорядочивает элементы управления определенным образом, согласно MSDN:

... для вертикальных направлений потока, управление FlowLayoutPanel вычисляет ширина подразумеваемого столбца из самого широкого дочернего элемента управления в столбец. Все остальные элементы управления в этом столбце с Якорь или Dockсвойства выравниваются или растягиваются, чтобы соответствовать этому подразумеваемому столбцу. поведение работает аналогичным образом для горизонтальных направлений потока.

Это не идеально, но вы можете сделать это изначально, если одно дочернее управление установлено на ту же ширину, что и контейнер, а остальные элементы управления установлены на Dock.

Ответ 6

Здесь нет необходимости в FlowLayoutPanel.

Вы должны иметь возможность делать то, что хотите, с помощью обычного Panel управления Panel. Закрепите его на всех четырех сторонах, чтобы он растянулся с вашей формой, затем добавьте свои кнопки и установите их все в Dock: Top.

Работа выполнена.

Ответ 7

как было сказано в других ответах, самой панели достаточно, чтобы обрабатывать ваши кнопки. Бит кода, который работает для меня:

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

Хорошего дня.