Поделиться через


Автоматическое масштабирование в Windows Forms

Автоматическое масштабирование позволяет форме и его элементам управления, разработанным на одном компьютере с определенным разрешением дисплея или системным шрифтом, отображаться соответствующим образом на другом компьютере с другим разрешением или системным шрифтом. Он гарантирует, что форма и его элементы управления будут интеллектуально изменять размер, чтобы обеспечить согласованность с собственными окнами и другими приложениями на компьютерах пользователей и других разработчиков. Поддержка .NET Framework автоматического масштабирования и визуальных стилей позволяет приложениям .NET Framework сохранять единый стиль и внешний вид, аналогичный собственным приложениям Windows на каждом компьютере пользователя.

В большинстве случаев автоматическое масштабирование работает должным образом в .NET Framework версии 2.0 и более поздних версий. Однако изменения схемы шрифтов могут быть проблематичными. Пример решения этой проблемы см. в статье Практическое руководство. Реагирование на изменения схемы шрифтов в приложении Windows Forms.

Необходимость автоматического масштабирования

Без автоматического масштабирования приложение, предназначенное для одного разрешения дисплея или шрифта, будет отображаться слишком маленьким или слишком большим при изменении разрешения или шрифта. Например, если приложение разработано с использованием Tahoma размером 9 как основного уровня, то без корректировки оно будет отображаться слишком маленьким при запуске на компьютере, где системный шрифт Tahoma имеет размер 12. Текстовые элементы, такие как заголовки, меню, содержимое текстового поля и т. д., будут отображаться меньше других приложений. Кроме того, размер элементов пользовательского интерфейса, содержащих текст, например строку заголовка, меню и многие элементы управления, зависят от используемого шрифта. В этом примере эти элементы также будут отображаться относительно меньше.

Аналогичная ситуация возникает, когда приложение предназначено для определенного разрешения дисплея. Наиболее распространенное разрешение дисплея составляет 96 точек на дюйм (DPI), что равно масштабу дисплея 100%, но дисплеи с более высоким разрешением, поддерживающие 125%, 150%, 200% (которые соответственно равны 120, 144 и 192 DPI), и выше, становятся более распространенными. Без корректировки приложение, особенно графическое, предназначенное для одного разрешения, будет отображаться слишком большое или слишком небольшое при выполнении в другом разрешении.

Автоматическое масштабирование стремится решить эти проблемы, автоматически изменяя размер формы и её дочерних элементов управления в соответствии с относительным размером шрифта или разрешением дисплея. Операционная система Windows поддерживает автоматическое масштабирование диалоговых окон с помощью относительной единицы измерения, называемой единицами диалоговых окон. Единица диалога основана на системном шрифте, и её связь с пикселями можно определить с помощью функции SDK Win32 GetDialogBaseUnits. Когда пользователь изменяет тему, используемую Windows, все диалоговые окна автоматически настраиваются соответствующим образом. Кроме того, платформа .NET Framework поддерживает автоматическое масштабирование в соответствии с системным шрифтом по умолчанию или разрешением дисплея. При необходимости автоматическое масштабирование можно отключить в приложении.

Исходная поддержка автоматического масштабирования

Версии 1.0 и 1.1 платформы .NET Framework поддерживают автоматическое масштабирование простым способом, который зависит от шрифта Windows по умолчанию, используемого для пользовательского интерфейса, представленного значением пакета SDK Win32 DEFAULT_GUI_FONT. Этот шрифт обычно изменяется только при изменении разрешения дисплея. Для реализации автоматического масштабирования использовался следующий механизм:

  1. Во время разработки свойство AutoScaleBaseSize (которое сейчас устарело) было установлено на высоту и ширину системного шрифта по умолчанию на компьютере разработчика.

  2. Во время выполнения системный шрифт компьютера пользователя по умолчанию использовался для инициализации свойства Font класса Form.

  3. Перед отображением формы вызывается метод ApplyAutoScaling для масштабирования формы. Этот метод вычисляет относительные размеры шкалы из AutoScaleBaseSize и Font, затем вызывает метод Scale для фактического масштабирования формы и её дочерних элементов.

  4. Значение AutoScaleBaseSize было обновлено таким образом, чтобы последующие вызовы ApplyAutoScaling не приводили к постепенному изменению размера формы.

Хотя этот механизм был достаточно для большинства целей, он страдал от следующих ограничений:

  • Так как свойство AutoScaleBaseSize представляет базовый размер шрифта в виде целых значений, возникают ошибки округления, которые становятся очевидными при циклической смене разрешений формы.

  • Автоматическое масштабирование было реализовано только в классе Form, а не в классе ContainerControl. В результате пользовательские элементы управления будут правильно масштабироваться только в том случае, если пользовательский элемент управления был разработан в том же разрешении, что и форма, и она была помещена в форму во время разработки.

  • Формы и их дочерние элементы управления могут быть одновременно разработаны несколькими разработчиками, если их разрешения компьютеров были одинаковыми. Аналогичным образом наследование формы также зависит от разрешения, связанного с родительской формой.

  • Он несовместим с более новыми диспетчерами макетов, представленными с .NET Framework версии 2.0, например FlowLayoutPanel и TableLayoutPanel.

  • Она не поддерживает масштабирование непосредственно на основе разрешения дисплея, необходимого для совместимости с .NET Compact Framework.

Хотя этот механизм сохраняется в .NET Framework версии 2.0 для обеспечения обратной совместимости, он был заменен более надежным механизмом масштабирования, описанным далее. В результате AutoScale, ApplyAutoScaling, AutoScaleBaseSizeи некоторые перегрузки Scale помечены как устаревшие.

Заметка

При обновлении устаревшего кода до .NET Framework версии 2.0 можно безопасно удалить ссылки на эти члены.

Текущая поддержка автоматического масштабирования

Платформа .NET Framework версии 2.0 заменяет предыдущие ограничения, введя следующие изменения в автоматическом масштабировании Windows Forms:

  • Базовая поддержка масштабирования была перемещена в класс ContainerControl, чтобы формы, собственные составные элементы управления и пользовательские элементы управления получали единую поддержку масштабирования. Добавлены новые члены AutoScaleFactor, AutoScaleDimensions, AutoScaleMode и PerformAutoScale.

  • Класс Control также имеет несколько новых членов, позволяющих участвовать в масштабировании и поддерживать смешанное масштабирование в одной форме. В частности, члены Scale, ScaleChildrenи GetScaledBounds поддерживают масштабирование.

  • Добавлена поддержка масштабирования на основе разрешения экрана для дополнения поддержки системных шрифтов, как определено перечислением AutoScaleMode. Этот режим совместим с автоматическим масштабированием, поддерживаемым .NET Compact Framework, что упрощает миграцию приложений.

  • Совместимость с менеджерами макетов, такими как FlowLayoutPanel и TableLayoutPanel, добавлена в реализацию автоматического масштабирования.

  • Коэффициенты масштабирования теперь представляются как значения с плавающей запятой, как правило, с помощью структуры SizeF, поэтому округление ошибок практически устранено.

Осторожность

Произвольные смеси режимов DPI и масштабирования шрифтов не поддерживаются. Хотя вы можете масштабировать элемент управления пользователем с помощью одного режима (например, DPI) и поместить его в форму с помощью другого режима (шрифта) без проблем, но сочетание базовой формы в одном режиме и производной форме в другой может привести к непредвиденным результатам.

Автоматическое масштабирование в действии

Windows Forms теперь использует следующую логику для автоматического масштабирования форм и их содержимого:

  1. На этапе проектирования каждый ContainerControl записывает режим масштабирования и текущее разрешение в AutoScaleMode и AutoScaleDimensionsсоответственно.

  2. Во время выполнения фактическое разрешение хранится в свойстве CurrentAutoScaleDimensions. Свойство AutoScaleFactor динамически вычисляет соотношение между разрешением масштабирования во время выполнения и времени разработки.

  3. При загрузке формы, если значения CurrentAutoScaleDimensions и AutoScaleDimensions отличаются, вызывается метод PerformAutoScale для масштабирования элемента управления и его дочерних элементов. Этот метод приостанавливает макет и вызывает метод Scale для выполнения фактического масштабирования. После этого значение AutoScaleDimensions обновляется, чтобы избежать прогрессивного масштабирования.

  4. PerformAutoScale также вызывается автоматически в следующих ситуациях:

    • В ответ на событие OnFontChanged, если режим масштабирования Font.

    • Когда возобновляется макет управляющего элемента контейнера и обнаруживается изменение в свойствах AutoScaleDimensions или AutoScaleMode.

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

  5. Дочерние элементы управления могут изменять поведение масштабирования с помощью нескольких средств:

    • Свойство ScaleChildren можно переопределить, чтобы определить, следует ли масштабировать дочерние элементы управления.

    • Метод GetScaledBounds можно переопределить, чтобы изменить границы масштабирования элемента управления, но не логику масштабирования.

    • Метод ScaleControl можно переопределить, чтобы изменить логику масштабирования для текущего элемента управления.

См. также