Автоматическое масштабирование в Windows Forms
Автоматическое масштабирование позволяет форме и ее элементам управления, разработанным на одном компьютере с использованием определенного разрешения или системных шрифтов, правильно отображаться на другом компьютере с другим разрешением или системным шрифтом. Оно гарантирует, что размеры формы и ее элементов управления будут изменяться автоматически в соответствии с приложениями Windows и другими приложениями на компьютерах пользователя и разработчика. Поддержка автоматического масштабирования и стилей оформления в .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 поддерживает автоматическое масштабирование диалоговых окон с помощью относительной единицы измерения, называемой единицей размера диалогового окна. Единица размера диалогового окна основана на системном шрифте, а ее связь с пикселями можно определить с помощью функции GetDialogBaseUnits
пакета Win32 SDK. При изменении темы, используемой Windows, все диалоговые окна автоматически настраиваются соответствующим образом. Кроме того .NET Framework поддерживает автоматическое масштабирование в соответствии со стандартным системным шрифтом или разрешением экрана. При необходимости автоматическое масштабирование можно отключить в приложении.
Исходная поддержка автоматического масштабирования
в .NET Framework 1.0 и 1.1 автоматическое масштабирование поддерживалось простым способом и зависело от шрифта Windows, используемого по умолчанию для пользовательского интерфейса. Этот шрифт представлен в пакете Win32 SDK значением DEFAULT_GUI_FONT. Обычно этот шрифт изменяется только при изменении разрешения экрана. Для реализации автоматического масштабирования применялся описанный ниже механизм.
Во время разработки свойству AutoScaleBaseSize (которое теперь устарело) присваивалась высота и ширина системного шрифта по умолчанию на компьютере разработчика.
Во время выполнения для инициализации свойства Font класса Form использовался стандартный системный шрифт компьютера пользователя.
Перед отображением формы вызывался метод ApplyAutoScaling для ее масштабирования. Этот метод вычислял относительный масштаб с помощью свойств AutoScaleBaseSize и Font, а затем вызывал метод Scale для масштабирования формы и ее дочерних элементов.
Значение свойства AutoScaleBaseSize обновлялось таким образом, чтобы последующие вызовы ApplyAutoScaling не продолжали изменять размер формы.
Этого механизма было достаточно для большинства целей, но он имел ряд ограничений.
Так как AutoScaleBaseSize свойство представляет базовый размер шрифта в виде целочисленные значения, погрешности округления становились заметны, когда форма проходила через ряд разрешений.
Автоматическое масштабирование было реализовано только в классе Form, но не в классе ContainerControl. В результате пользовательский элемент управления масштабировался корректно, только если он был разработан с тем же разрешением, что и форма, и был помещен в форму во время разработки.
Несколько разработчиков могли параллельно разрабатывать формы и их дочерние элементы управления, только если разрешение экрана на их компьютерах совпадало. Аналогичным образом наследование форм зависело от разрешения родительской формы.
Механизм несовместим с новыми диспетчерами макетов, добавленными в .NET Framework версии 2.0, такими как FlowLayoutPanel и TableLayoutPanel.
Механизм не поддерживает масштабирование непосредственно на основе разрешения экрана, необходимое для совместимости с .NET Compact Framework.
Хотя этот механизм сохранился в .NET Framework версии 2.0 для обеспечения обратной совместимости, на смену ему пришел более надежный механизм масштабирования, описанный ниже. Как следствие, методы AutoScale, ApplyAutoScaling, AutoScaleBaseSize и некоторые перегрузки Scale помечены как устаревшие.
Note
Вы можете спокойно удалить ссылки на эти члены при обновлении старого кода до .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, что позволило практически устранить ошибки округления.
Caution
Произвольные сочетания режимов масштабирования на основе разрешения экрана и размера шрифта не поддерживаются. Вы без всяких проблем можете масштабировать пользовательский элемент управления в одном режиме (например, на основе разрешения экрана) и поместить его в форму с помощью другого режима (на основе размера шрифта), но использование базовой формы в одном режиме и производной формы в другом может привести к непредвиденным результатам.
Автоматическое масштабирование в действии
В Windows Forms для автоматического масштабирования формы и ее содержимого теперь используется описанная ниже логика.
Во время разработки каждый объект ContainerControl регистрирует режим масштабирования и его текущее разрешение в свойствах AutoScaleMode и AutoScaleDimensions соответственно.
Во время выполнения фактическое разрешение хранится в свойстве CurrentAutoScaleDimensions. Свойство AutoScaleFactor динамически вычисляет отношение между разрешением во время выполнения и разрешением во время разработки.
Если при загрузке формы значения CurrentAutoScaleDimensions и AutoScaleDimensions различны, то для масштабирования элемента управления и его дочерних элементов вызывается метод PerformAutoScale. Этот метод приостанавливает размещение и вызывает метод Scale для выполнения фактического масштабирования. Впоследствии значение AutoScaleDimensions обновляется во избежание прогрессивного масштабирования.
Метод PerformAutoScale также вызывается автоматически в перечисленных ниже ситуациях.
В ответ на событие OnFontChanged, если используется режим масштабирования Font.
Если при возобновлении размещения элементов управления внутри контейнера обнаруживается изменение свойства AutoScaleDimensions или AutoScaleMode.
При масштабировании родительского объекта ContainerControl, как указанно выше. Каждый контейнерный элемент управления отвечает за масштабирование своих дочерних элементов с помощью своих собственных коэффициентов масштабирования, а не коэффициентов его родительского контейнера.
Поведение дочерних элементов управления при масштабировании может изменяться несколькими способами.
Можно переопределить свойство ScaleChildren, чтобы указать, следует ли масштабировать дочерние элементы управления.
Можно переопределить метод GetScaledBounds для корректировки границ, до которых масштабируется элемент управления, но не логики масштабирования.
Можно переопределить метод ScaleControl для изменения логики масштабирования текущего элемента управления.