Размеры и расположение фигур

51

Как уже известно, жестко закодированные размеры — обычно не лучший подход для создания пользовательских интерфейсов. Они ограничивают возможности обработки динамического содержимого и затрудняют локализацию приложения для других языков.

При рисовании фигур эти соображения не всегда применимы. Часто требуется более тонкий контроль над расположением фигур. Однако есть много случаев, когда можно обеспечить более высокую гибкость дизайна. Как Ellipse, так и Rectangle умеют изменять свой размер так, чтобы заполнять доступное пространство.

Если свойства Height и Width не применяются, то размер фигуры устанавливается на основе ее контейнера. В предыдущем примере удаление значений Height и Width (и пропуск значений MinHeight и MinWidth) приведут к тому, что фигуры уменьшатся до минимальных размеров, поскольку размер StackPanel установлен так, чтобы заполнялось все содержимое. Однако если заставить StackPanel принять полную ширину окна (установив свойство Horizontal Alignment в Stretch), затем также установить свойство HorizontalAlignment эллипса в Stretch и удалить свойство Width эллипса, то эллипс заполнит всю ширину окна.

Более наглядный пример можно получить с помощью контейнера Grid. Если используются пропорциональные размеры строк (по умолчанию так оно и есть), то можно создать эллипс, заполняющий окно, с помощью такого упрощенного кода разметки:

<Grid>
   <Ellipse Fill = "Yellow" Stroke="Blue"></Ellipse>
</Grid>

Здесь Grid заполняет все окно. Контейнер Grid содержит единственную строку с пропорциональным размером, которая заполняет его целиком. И, наконец, эллипс заполняет всю строку.

Поведение, касающееся выбора размера, зависит от значения свойства Stretch (которое определено в классе Shape). По умолчанию оно установлено в Fill, что растягивает фигуру так, чтобы она заполнила весь контейнер, если ее размер не указан явно. Все возможные значения перечисления Stretch описаны ниже:

Fill

Фигура растягивается по ширине и высоте для полного заполнения контейнера. (В случае явной установки высоты и ширины эта настройка не имеет эффекта.)

None

Фигура не растягивается. Если не установить ненулевые значения для ширины и высоты (с помощью свойств Height и Width или MinHeight и MinWidth), то фигура вообще не появится

Uniform

Ширина и высота увеличиваются пропорционально, пока фигура не достигнет границ контейнера. В случае эллипса получится самая большая окружность, которая умещается в окно. Если же применять это с прямоугольником, то получится максимально возможный квадрат. (При явной установке высоты и ширины фигура будет находиться в указанных границах. Например, если установить Width в 10 и Height в 100 для прямоугольника, то получится только квадрат размером 10x10.)

UniformToFill

Ширина и высота устанавливаются пропорционально, пока фигура не заполнит всю доступную высоту и ширину. Например, если поместить прямоугольник с такой установкой размера в окно 100x200 единиц, то получится прямоугольник размером 200x200, и часть его будет усечена. (В случае явной установки высоты и ширины фигура будет вписана в указанные размеры. Например, если установить Width в 10 и Height в 100 для прямоугольника, то получится прямоугольник 100x100, усеченный так, чтобы уместиться в область 10x100.)

На рисунке демонстрируется разница между Fill, Uniform и UniformToFill:

Разница между значениями свойства Stretch

Обычно значение Stretch, равное Fill — это то же самое, что установка HorizontalAlignment и VerticalAlignment в Stretch. Разница проявляется при установке фиксированных значений для Width и Height фигуры. В этом случае значения HorizontalAlignment и VerticalAlignment просто игнорируются. Однако установка Stretch все же дает эффект — она определяет то, как содержимое фигуры размещается в пределах заданных границ.

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

До сих пор было показано, как задавать размеры Rectangle и Ellipse, но как насчет точного их размещения? Фигуры WPF используют ту же систему компоновки, что и любой другой элемент. Однако некоторые контейнеры компоновки для этого не подходят. Например, StackPanel, DockPanel и WrapPanel часто оказываются вовсе не тем, что нужно, поскольку они предназначены для разделения элементов.

Контейнер Grid несколько более гибкий, потому что позволяет разместить произвольное количество элементов в одной и той же ячейке (хотя и не дает возможности разместить квадраты и эллипсы в разных частях одной ячейки). Идеальным является контейнер Canvas, который требует явного указания координат каждой фигуры через присоединенные свойства Left, Top, Right и Bottom. Он предоставляет полный контроль над перекрытием фигур.

Пройди тесты
Лучший чат для C# программистов