Як змусити flowlayoutpanel нормально працювати stack overflow російською

Намагаюся присобачить FlowLayoutPanel з вирівнювання елементів знизу вгору.
Або я зовсім не вмію нею користуватися, або вона взагалі працює якось не так.

  1. Що це за -6, складові різницю між шириною панелі і контролів в ній?
  2. При зменшенні ширини елементів ширина панелі не зменшується.
  3. Нижній Padding в 2 рази більше ніж повинен бути.
  4. Немає горизонтального скролла, якщо переповнення відбувається через паддінга.
  5. Ті частини, які не поміщаються через паддінга, опиняються поза області прокрутки. У тому числі зверху.
  1. Що це за -6, складові різницю між шириною панелі і контролів в ній?

Ця різниця через Margin -ів вкладених контролів. Значення за замовчуванням - 3px з усіх боків.

  1. При зменшенні ширини елементів ширина панелі не зменшується.

Для того щоб ширина панелі могла змінювати розмір, потрібно виставити властивість AutoSize = true. а якщо хочете щоб вона вміла не тільки розширюватися, але і зменшуватися, то властивість AutoSizeMode = AutoSizeMode.GrowAndShrink.

  1. Нижній Padding в 2 рази більше ніж повинен бути.
  2. Немає горизонтального скролла, якщо переповнення відбувається через паддінга.
  3. Ті частини, які не поміщаються через паддінга, опиняються поза області прокрутки. У тому числі зверху.

З падінгамі ця панель нормально працює тільки при включеному AutoSize і відключеному AutoScroll. подробиці нижче.

Нарешті добрався написати оновлення до відповіді. Отже:

А якщо трохи точніше, то всіх контролів-контейнерів, успадкованих від ScrollableControl. Для бажаючих самостійно все перевірити і любителів копатися в коді вихідні тут. Дослідження проводилися на рідних .NET-івських формах. У Mono поведінка може відрізнятися.

В даному питанні нас цікавлять такі властивості панелі: AutoSize. AutoSizeMode. AutoScroll. Padding. MaximumSize. Dock і їх взаємний вплив один на одного, вплив на зовнішній вигляд і поведінку панелі. На перший погляд все просто, але є деяка кількість тарганів, здатних відняти масу часу і, можливо, нервів.

Почнемо з AutoSize - згідно з документацією, якщо включити дане властивість, то розмір контрола буде підігнаний під розмір його вмісту. Цим поведінкою можна до певної міри керувати використовуючи властивості MaximumSize і MinimumSize. думаю тут пояснення не потрібні. А також властивістю AutoSizeMode. яке може приймати одне з двох значень: GrowOnly і GrowAndShrink. У першому випадку панель буде збільшуватися щоб відобразити на собі весь контент, але не буде стискатися якщо контент менше, в другому зміна розміру відбувається в обидві сторони. Якщо крім цього задіяти властивість Padding. то розмір елемента буде підігнаний з урахуванням відступів. Додаємо Dock. будь-який крім Fill і знову отримуємо те, що очікуємо. Відступи враховані, контент відображається весь, якщо вміщується в батьківський котроль нашої панелі.

Якщо все очікувано - навіщо стільки тексту? А ось навіщо, спробуйте додати сюди AutoScrol. Якщо властивість MaximumSize НЕ виставлено, і включений AutoSize. то нічого не станеться. Взагалі. Воно цілком логічно, навіщо включати скрол якщо все уміщається і так. Тепер виставимо MaximumSize так, щоб контент перестав уміщатися, наприклад по висоті. З'являються скрол бари і починаються чудеса. Сколбари з'являються відразу обидва, навіть якщо контент вміщується по ширині, тому що вертикальний скролбар при включенні зменшує ширину видимій частині панелі і контент перестає вміщатися по ширині. А як же AutoSize. а ні як, він нічого не знає про скролбар і продовжує обчислювати ширину панелі по ширині її контенту.

Далі все чудесатее. Здається, що ситуацію можна виправити за допомогою властивості Padding. про нього то AutoSize знає і враховує. Так можна, але тільки якщо використовувати, в нашому випадку з вертикальним скролом, правий відступ. AutoSize перерахує розмір з його обліком і скролбар належиться нема на контент, провокуючи появу другого скролбара, а на відступ, якщо розмір відступу достатній. Додамо відступ зліва - все добре, розмір знову перерахують правильно. Додамо нижній відступ - нічого не сталося, ніби ми його і не додавали. Гаразд, не страшно, ну пропав відступ і чорт з ним, контент то видно і Скрол. Додамо верхній відступ - "Шеф! Все пропало!" відступ то видно, але рівно на розмір цього відступу контент з'їхав вниз і скрол не дозволяє змістити контент так, що б він став видно весь. Відповідно якщо у нас активний горизонтальний скролбар, то такий же ефект буде від застосування лівого відступу. Ще цікавий момент, якщо вказати тільки лівий відступ, причому розміри більше ніж ширина скролбара, то відступ буде видно, вертикальний скролбар належиться на контент, АЛЕ горизонтальний скролбар не з'явиться, тому що ширини досить для розміщення контенту.

Причина такого неподобства, як мені вдалося з'ясувати з початкових кодів (тиць) криється в тому, що, при перерахунку розмірів клієнтської області, враховуються тільки нижній і правий відступи.

Можливо я перерахував не всі варіанти дивної поведінки відступів на панелях, але загальну суть проблеми постарався розкрити повністю.

Для себе, я свого часу знайшов спосіб отримати бажану картинку, може стане в нагоді і вам.

Чому знадобилася зовнішня панель? тут все просто, якщо використовувати ручний підбір розміру FlowLayoutPanel. то доведеться реагувати на зміну будь-якого з вкладених елементів і потенційне додавання або видалення елементів. Для зовнішньої же панелі, потрібно стежити тільки за зміною розміру FlowLayoutPanel.

Схожі статті