Як отримати управління в 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.