Автоматическая упаковка FlowLayoutPanel не работает с автоматическим изменением размера

.NET Framework / C # / Windows Forms

Я бы хотел, чтобы FlowLayoutPanel автоматически настраивал ширину или высоту в зависимости от количества элементов управления внутри него. Также следует изменить количество столбцов / строк, если места недостаточно (обернуть его содержимое). Проблема в том, что если я установил авторазмер, тогда панель flowlayoutpanel не оборачивает элементы управления, которые я вставляю. Какое решение лучше?

Спасибо!


person Yegor    schedule 24.09.2009    source источник
comment
Я удивлен, что никто не ответил на этот вопрос, у меня такая же проблема. Удар?   -  person echo    schedule 25.12.2009
comment
TableLayoutPanel может быть лучшим решением для вас - он имеет встроенную поддержку автоматического изменения размера столбцов и строк, а также автоматического изменения размера для всей панели.   -  person Bevan    schedule 28.02.2010


Ответы (6)


Установите для параметра MaximumSize FlowLayoutPanel значение ширины, по которой он будет обтекаться. Установите WrapContents = true.

person Oliver Bock    schedule 15.05.2014
comment
установка максимального размера все еще требует расчета - person Smith; 05.08.2016

Вы пробовали использовать TableLayoutPanel? Это очень полезно для размещения элементов управления внутри ячеек.

person Icono123    schedule 17.02.2010
comment
Использование TableLayoutPanel a) имеет совершенно другой вариант использования, а b) - еще худший кошмар. - person Yoda; 26.09.2019

В разработке программного обеспечения нет ничего невозможного. Невозможное просто занимает больше времени.

Я исследовал проблему. Если действительно нужна Flow Layout, это можно сделать, немного поработав. Поскольку FlowLayoutPanel размещает элементы управления, особо не задумываясь о количестве строк / столбцов, а скорее о совокупной ширине / высоте, вам может потребоваться отслеживать, сколько элементов управления вы уже добавили. Прежде всего, установите для параметра autosize значение false, а затем подключите собственную логику управления размером к событиям ControlAdded / ControlRemoved. Идея состоит в том, чтобы установить ширину и высоту панели таким образом, чтобы вы получили желаемое количество столбцов.

Грязное доказательство концепции:

private void flowLayoutPanel1_ControlAdded(object sender, ControlEventArgs e)
    {
        int count = this.flowLayoutPanel1.Controls.Count;
        if (count % 4 == 0)
        {
            this.flowLayoutPanel1.Height = this.flowLayoutPanel1.Height + 70;
        }
    }

если панель изначально имеет ширину для 4 элементов управления, она будет генерировать строку для новых. Обработчик ControlRemoved должен проверить то же самое и уменьшить высоту панели или получить все содержащиеся элементы управления и разместить их снова. Вы должны подумать об этом, это может быть не то, что вам нужно. Это зависит от сценария использования. Все ли элементы управления будут одного размера? Если нет, вам понадобится более сложная логика.

Но на самом деле подумайте о макете таблицы - вы можете обернуть его во вспомогательный класс или получить из него новый элемент управления, где вы разрешите всю логику размещения элементов управления. FlowLayout упрощает добавление и удаление элементов управления, но затем включается код управления размером. TableLayout дает вам хороший механизм для строк и столбцов, управлять шириной и высотой проще, но вам понадобится больше кода для изменения размещения всех контролирует, хотите ли вы удалить его из формы динамически.

person usualexpat    schedule 17.02.2010

Если возможно, я предлагаю вам изменить размер FlowLayoutPanel, чтобы он использовал всю доступную ширину, а затем закрепить его сверху, слева и справа. Это должно заставить его расти в высоту по мере необходимости, при этом элементы управления все еще обертываются.

person Eiríkur Fannar Torfason    schedule 26.07.2011
comment
Но как сообщить FlowLayoutPanel об автоматическом обновлении своего свойства Height в зависимости от того, сколько строк необходимо создать при переносе содержимого? Мне нравится идея привязки сверху, слева и справа, но Height моего FlowLayoutPanel, похоже, остается неизменным ... - person binki; 13.06.2014

Вы добавляете элементы управления динамически в зависимости от действий пользователя? Боюсь, вам придется изменять свойства FlowLayout на лету в коде, когда добавляете в него новые элементы управления, а затем обновление формы поможет.

person usualexpat    schedule 17.02.2010

Я знаю, что это старый поток, но если кто-то еще задается вопросом, то вот решение, которое я создал - установите для autosize значение true на панели и вызовите этот метод расширения из события Resize панели потока:

public static void ReOrganise(this FlowLayoutPanel panel)
{
    var width = 0;
    Control prevChildCtrl = null;

    panel.SuspendLayout();

    //Clear flow breaks
    foreach (Control childCtrl in panel.Controls)
    {
        panel.SetFlowBreak(childCtrl, false);
    }

    foreach (Control childCtrl in panel.Controls)
    {
        width = width + childCtrl.Width;

        if(width > panel.Width && prevChildCtrl != null)
        {
            panel.SetFlowBreak(prevChildCtrl, true);
            width = childCtrl.Width;
        }

        prevChildCtrl = childCtrl;
    }

    panel.ResumeLayout();
}
person DavidWainwright    schedule 08.05.2019