Як отримати управління в WPF, щоб заповнити доступний простір?


303

Деякі елементи керування WPF (як-от Button), здається, із задоволенням споживають увесь доступний простір у своєму контейнері, якщо не вказати висоту, яку він повинен мати.

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

Якщо ви помістите цих хлопців у клітинку в UniformGrid, вони розширяться, щоб відповідати наявному простору. Однак UniformGridекземпляри підходять не у всіх ситуаціях. Що робити, якщо у вас є сітка з деякими рядками, встановленими на * висоту, щоб розділити висоту між собою та іншими * рядками? Що робити, якщо у вас є StackPanelі є Label, a Listі a Button, як ви можете отримати список, щоб зайняти весь простір, не з'їдений етикеткою та кнопкою?

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

Змінний розмір GUI буде досить жахливо , якщо ви повинні були грати з Height, Width, MinHeight, і MinWidthт.д.

Чи можете ви прив’язати свої Heightта Widthвластивості до осередку сітки, яку ви займаєте? Або є інший спосіб зробити це?


1
UniformGrid - дивовижний, мій новий тег goto за замовчуванням. Мені сподобалася простота Stackpanels (нагадує мене про діву), але Uniform Grid робить саме те, що мені потрібно.
Терранс

Re UniformGrid. Акцент робиться на Уніформа. Здається, ви не можете налаштувати ширину стовпців без висоти рядків. Він підходить лише в тому випадку, якщо кожен вміст має однаковий розмір. Я замінив свій StackPanel на Grid, а Stretch тоді працював так, як я цього очікував.
pdschuller

Ця стаття допомогла мені розтягнути текстові поля.
jpaugh

Відповіді:


162

Кожен елемент управління, що випливає з Panelрізної логіки компонування, виконаної в Measure()та Arrange():

  • Measure() визначає розмір панелі та кожного з її дітей
  • Arrange() визначає прямокутник, куди подається кожен елемент управління

Остання дитина DockPanelзаповнює залишок місця. Ви можете відключити цю поведінку, встановивши LastChildвластивість на false.

StackPanelПрошу кожна дитина для його потрібного розміру , а потім складає їх. Панель стеків викликає Measure()кожну дитину з наявним розміром, Infinityа потім використовує бажаний розмір дитини.

А Gridзаймає весь доступний простір, однак, він встановить кожну дитину на потрібний розмір, а потім відцентрує їх у комірці.

Ви можете реалізувати власну логіку компонування, виходячи з Panel а потім переосмислюючи MeasureOverride()і ArrangeOverride().

Дивіться цю статтю для простого прикладу.


8
Посилання зараз мертве
користувач3690202

6
@ user3690202 Archive.org - твій друг. Посилання реанімація.
ruffin

4
Тема все ще існує в MSDN, але посилання змінилося на це: docs.microsoft.com/en-us/dotnet/framework/wpf/controls/…
Andrea Antonangeli

2
The last child of the DockPanel fills the remaining space: це було відсутнім ключем до мого розуміння. Я завжди хоча, що елемент без явного Dock заповнив простір.
Плямистий

238

Є також деякі властивості, які ви можете встановити, щоб змусити елемент керувати наявним простором, коли б інакше це не було. Наприклад, ви можете сказати:

HorizontalContentAlignment="Stretch"

... змусити вміст елемента керування розтягуватися по горизонталі. Або ви можете сказати:

HorizontalAlignment="Stretch"

... змусити сам елемент управління розтягнутися горизонтально, щоб заповнити його батьківський.


88
Найвідоміша панель, згадана у всіх цих випадках, - StackPanel. Він не містить властивостей ContentAlignment і встановлення його дітей на Stretch не матиме ефекту всередині сітки розміром зірки. Дуже засмучує. Це майже так, як якщо б StackPanel був першим контейнером, про який написала команда WPF, і це страждає за це.
Brent Schooley

4
@Brent - ах! Я застряг у спробі, щоб вміст моєї стекпанелі правильно заповнився. Дякую! Я думав, що це просто те, що я робив дуже неправильно.
Ешлі Гренон

8
Панель @townsean Stack дуже обмежена, ви можете отримати подібну поведінку при розтягуванні за допомогою UniformGrid та встановленням рядків або стовпців на 0
ForbesLindesay

2
@ Tuskan360 UniformGrid дозволяє клітинам бути однакового розміру. Я використав сітку в підсумку, здається, працює. Прикро, як StackPanel не робить того, на що, здавалося б, призначений.
TarkaDaal

4
@TarkaDaal, так, UniformGrid, якщо все однакового розміру, Grid, якщо ви хочете вказати складні відносні розміри, панель укладайте на розмір просто залежно від вмісту і ігноруйте, скільки місця доступно.
ForbesLindesay

18

Що ж, я зрозумів це сам, одразу після публікації, що є найбільш неприємним способом. :)

Здається, кожен член StackPanel просто заповнить мінімальний запитуваний розмір.

У DockPanel я стикував речі в неправильному порядку. Якщо TextBox або ListBox - єдиний стикований елемент без вирівнювання, або якщо він останній доданий, вони заповнять залишок місця, як хотілося.

Мені б хотілося побачити більш елегантний метод поводження з цим, але це буде.


Я просто хочу зазначити (на цьому старому питанні!), Що "без вирівнювання" є ключовою фразою тут, принаймні, це було для мене.
MikeBaz - MSFT

4

Використовуйте властивості макета HorizontalAlignment та VerticalAlignment . Вони контролюють, як елемент використовує простір, який він має у своєму батьківському, коли є більше місця, ніж цього вимагає елемент.

Наприклад, ширина StackPanel буде такою ж широкою, як і найширший елемент, який він містить. Отже, всі вужчі елементи мають трохи зайвого простору. Властивості вирівнювання керують тим, що дочірній елемент робить із додатковим простором.

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


31
Якби це завжди було правдою, оригінального питання не було б задано. Візьмемо, наприклад, горизонтальний StackPanel з міткою та TextBox. Праворуч від TextBox є додатковий простір. TextBox встановлений на Автоматична ширина. Якщо встановити Stretch для HorizontalAlignment, це не змусить TextBox заповнити залишився пробіл.
Brent Schooley

Ніщо не відповідає дійсності, але ця відповідь працює для моїх потреб: DockPanel, Image.
alehro
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.