Изменить шрифт windows forms

Обновлено: 04.07.2024

Вопросы:

Что в WinForms НЕ автоматическое масштабирование должным образом и поэтому следует избегать?

Какие руководящие принципы проектирования должны следовать программистам при написании кода WinForms, чтобы он автоматически масштабировался?

Рекомендации по дизайну, которые мы определили до сих пор:

Являются ли какие-либо из этих неправильных или неадекватных? Любые другие рекомендации, которые мы должны принять? Есть ли другие шаблоны, которых нужно избегать? Любые другие рекомендации по этому вопросу будут очень оценены.

Элементы управления, которые не поддерживают масштабирование должным образом:

ToolStripButton изображение. В конструкторе формы:

  • Установить ToolStrip.AutoSize = False
  • Установите ToolStrip.ImageScalingSize в соответствии с CreateGraphics.DpiX и .DpiY
  • При необходимости установите ToolStrip.AutoSize = True .

Рекомендации по дизайну:

Все контейнеры ContainerControls должны быть установлены на один и тот же AutoScaleMode = Font .
(Шрифт будет обрабатывать как изменения DPI, так и изменения в системном шрифте
настройка размера; DPI будет обрабатывать только изменения DPI, а не изменения в
системный размер шрифта.)

Все элементы управления на конкретном Panel или Container должны либо использовать привязку, либо докинг. Если вы их смешиваете, автомасштабирование, выполняемое этим Panel , будет часто ошибочным в тонких причудливых путях.

Если вы создаете макет должным образом reflowable/auto-size, то почти все работает точно так же, как и автоматически, с настройками по умолчанию, используемыми Visual Studio (а именно, AutoSizeMode = Font в родительской форме и Inherit на все остальное).

Единственная проблема заключается в том, что вы задали свойство Font в форме в дизайнере. Сгенерированный код сортирует задания по алфавиту, что означает, что AutoScaleDimensions будет назначаться до Font . К сожалению, это полностью нарушает логику автоматического масштабирования WinForms.

Исправление просто. Либо не устанавливайте свойство Font в конструкторе вообще (установите его в конструкторе формы), либо вручную измените порядок этих назначений (но тогда вы должны продолжать делать это каждый раз, когда вы редактируете форму в дизайнере). Voila, почти идеальное и полностью автоматическое масштабирование с минимальными хлопотами. Даже размеры формы масштабируются правильно.

Ниже перечислены известные проблемы, с которыми я сталкиваюсь:

Руководство, которое я написал на работе:

Чтобы поддержать его, добавьте манифест приложения в приложение и сообщите, что ваше приложение поддерживает Windows 10:

Затем добавьте app.config и объявите приложение Per Monitor Aware. Это выполняется сейчас в app.config и NOT в манифесте, как раньше!

Этот PerMonitorV2 является новым, поскольку обновление для разработчиков Windows 10:

DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2

  • Уведомления об изменении DPI дочернего окна. В контексте Per2 v2 все дерево окон уведомляется о любых изменениях DPI, которые происходят.

  • Масштабирование неклиентской области. Все окна автоматически будут иметь свою неклиентскую область, нарисованную чувствительным способом DPI. Звонки на EnableNonClientDpiScaling не требуется.

  • S настройка меню Win32. Все меню NTUSER, созданные в контекстах Per Monitor v2, будут масштабироваться для каждого монитора.

  • Диалоговое масштабирование. Диалоги Win32, созданные в контекстах Per Monitor v2, автоматически будут реагировать на изменения DPI.

  • Улучшено масштабирование элементов управления comctl32. Различные элементы управления comctl32 улучшили поведение масштабирования DPI в Per Monitor v2 контексты.

  • Улучшенное поведение в темах. Ручки UxTheme, открытые в контексте окна Per Monitor v2, будут работать с точки зрения DPI связанные с этим окном.

Теперь вы можете подписаться на 3 новых события, чтобы получать уведомления о изменениях DPI:

  • Control.DpiChangedAfterParent, который запускается. Происходит, когда параметр DPI для элемента управления изменяется программно после DPI изменить событие для его родительского элемента управления или формы.

  • Control.DpiChangedBeforeParent, который запускается, когда параметр DPI для элемента управления изменяется программно до изменения DPI событие для его родительского элемента управления или формы.

  • Form.DpiChanged, который запускается, когда параметр DPI изменяется на устройстве отображения, где отображается форма.

У вас также есть 3 вспомогательных метода обработки/масштабирования DPI:

Control.LogicalToDeviceUnits, который преобразует значение из логического в пиксели устройства.

Control.ScaleBitmapLogicalToDevice, который масштабирует растровое изображение для логического DPI для устройства.

Control.DeviceDpi, который возвращает DPI для текущего устройства.

Если у вас нет доступа к исходному коду, вы можете перейти к свойствам приложения в проводнике Windows, перейти к совместимости и выбрать System (Enhanced)

который активирует масштабирование GDI, чтобы улучшить обработку DPI:

Для приложений, основанных на GDI, Windows теперь может масштабировать DPI для каждого монитора. Это означает, что эти приложения будут, волшебным образом, чтобы распознать DPI на мониторе.

В дополнение к якорям, которые не работают очень хорошо: я бы сделал шаг дальше и сказал, что точное позиционирование (иначе, используя свойство Location) не очень хорошо работает с масштабированием шрифта. Мне пришлось решить эту проблему в двух разных проектах. В обоих случаях нам пришлось преобразовать расположение всех элементов управления WinForms в использование TableLayoutPanel и FlowLayoutPanel. Использование свойства Dock (обычно устанавливается для Fill) внутри TableLayoutPanel работает очень хорошо и отлично масштабируется с помощью системного шрифта DPI.

Недавно я столкнулся с этой проблемой, особенно в сочетании с масштабированием Visual Studio при открытии редактора в системе с высоким разрешением. Мне было лучше сохранить AutoScaleMode = Font , но установить шрифт шрифт по умолчанию, но указать размер в пикселе, а не то есть: Font = MS Sans; 11px . В коде я , затем reset шрифт по умолчанию: Font = SystemFonts.DefaultFont и все в порядке.

Здравствуйте! Сегодня мы добавим нашему калькулятору строку меню, будем менять шрифт и открывать дочерние формы. Погнали!

Строка меню - это та строка, которая расположена под строкой состояния (та, на которой есть кнопки "свернуть", "на весь экран" и "закрыть") Она есть не во всех программах, в основном в тех, где надо работать с файлами/данными и т.д.

Мы же добавим в нашу строку две меню - изменение шрифта и открытие самодельного текстового редактора.

Строка меню как элемент WinForms

Строка меню - это тоже элемент, как и кнопка, текст и др., так что можем мы его можем найти в панели элементов.

Перетаскиваем его на нашу форму и видим, что какой-то элемент перешел в самый низ, а сверху программы появился белый прямоугольник. Это и есть наша строка меню. Нажимаем на нее видим надпись "Вводить здесь" и поле для ввода. Как вы и без меня поняли, тут мы вводим название элементов меню.

Давайте назовем наш первый элемент - "Настройки", т.е. там пользователь будет менять настройки нашего калькулятора. После этого снизу от элемента появляется раскрывающийся панель - это внутренние элементы наших "настроек". Нажмите на стрелочку и в открывшийся меню мы видим четыре элемента: "MenuItem", "ComboBox", "Seperator" и "TextBox". Каждый из элементов есть и в панели элементов (кроме "Seperator") и вы, надеюсь, с ними уже знакомы. Если нет, то вот перечисление их функций:

  • MenuItem - это просто элемент, если на который вы наведете, из него выйдет еще менюшка с такими же элементами.
  • ComboBox (нет, это не коробка с "к-к-к-комбо!") - это раскрывающиеся меню с несколькими вариантами выбора, в котором можно выбрать только один.
  • Seperator - это просто перегородка или разделитель. Служит для разделения разных элементов. Удобен для разделения на категории.
  • TextBox - просто ввод текста. Можно, например, вписывать имя, или другие данные.
  • Label - в списке его нет, но чтобы его добавить надо вписать нужный текст в поле для ввода "Вводить здесь".

Просто введите текст "Открыть настройки" в поле для ввода "Вводить здесь".

Далее выбираем наш Label и открываем меню событий. Находим событие Click и устанавливаем ему метод SettingsOpen и далее жмем ПКМ по проекту и выбираем Добавить. -> Форма Windows. Называем новую форму "Настройки.cs" (да, я знаю, что лучше называть латиницей)

Дочерняя форма "Настройки.cs"

Теперь у нас есть вторая форма, но она не откроется, если ее не открыть. (да ладно) Чтобы это сделать надо зайти в наш метод SettingsOpen и создать в нем новый объект класса Настройки с именем settings (и зачем мы назвали его кириллицей. ) и пишем метод Show объекта settings .

Метод Show объекта класса позволяет показать какой-либо элемент. Однако не забывайте, что теперь форма Настройки - это дочерняя форма формы Form1, т.е. если вы закроете родительскую форму (Form1 если еще не поняли) то закроется и дочерняя. Чуть позднее мы обсудим вариант как открыть вторую форму не делая ее дочерней.

Изменение шрифта через FontDialog

Теперь заходим в конструктор формы Настройки.cs и добавляем в него FontDialog и Button с текстом "Выбрать шрифт". Задаем событию Click кнопки метод FontSelected . Теперь вписываем туда следующее:

Вы можете заметить, что его нет на форме, а он появился снизу, как MenuStrip . Так появляются фоновые или сторонние элементы. В нашем случае, он сторонний, ведь он открывает системное окно выбора шрифта Windows.

Нам надо выбрать шрифт калькулятора. Но как изменить сразу все элементы, ведь там их много? А вот так: в WinForms (и в WPF вроде бы тоже) если вы не устанавливаете свои значения определенным свойствам элементов формы, то они получают значения "по умолчанию", а это "по умолчанию" - это значения формы. Шрифт в том числе.

Однако, чтобы это сделать мы должны не менять значение шрифта по умолчанию (если значение изменено, то оно будет жирным). Но тут есть одна проблема - размер шрифта. К сожалению, если мы изменим хоть что-то, будь то размер шрифта или формат, весь шрифт будет показан как не по умолчанию и это вызывает некоторые проблемы, ведь мы сделали шрифт кнопок и первого операнда 15pt. У нас два варианта - либо сделать так, чтобы пользователь выбирал шрифт каждого элемента по отдельности, что будет долго и муторно как для разработчика, так и для пользователя, либо сделать кнопки и все другие элементы маленькими, что будет не особо красиво, если не сделать соответствующие правки. Я, пожалуй, сделаю кнопки маленькими.

Так, теперь всё, что нам надо сделать - задать нужные значения форме. А делать мы это будем обращаясь к свойству формы Font:

Заметьте, что у FontDialog нет шрифта, ведь сам элемент даже не видем и не имеет визуальных черт, а он лишь открывает сторонний диалог. Однако у него есть свойство Font, что у других элементов является шрифтом текста. Дело в том, что при вызове диалога шрифтов и выборе шрифта в нем FontDialog вставляет шрифт, который мы выбрали в свое свойство Font. У него также есть свойство DialogResult , но это только результат действия диалога, например, его отмена. ( DialogResult.Cancel )

Конец

Фух, этот урок я делал долго и нашел довольно много информации для вас. Надеюсь, вам понравилось. Также, если вы еще не подписаны на мой телеграмм канал, подписывайтесь (тык!) До скорого и удачи!

У меня есть основная форма. При нажатии Tools-> Options в меню моего приложения я показываю другую форму (OptionsForm), которая содержит параметры для изменения шрифта, используемого элементами управления. Я сохраняю выбранный шрифт в Properties: Settings: Default: some_object. Я также могу получить его и обновить свои элементы управления, но только нажатием кнопки в моей MainForm.

Я попытался вызвать функцию, написанную на MainForm, из OptionsForm, создав экземпляр MainForm для обновления элемента управления. Шрифт -> не работает.

Как убедиться, что всякий раз, когда я меняю шрифт в Properties: Settings: Default: some_object, все элементы управления отражают это изменение?

2 ответа

Эта одна строка может повлиять на шрифт каждого элемента управления в приложении, потому что теперь все они привязаны к одному и тому же параметру приложения. Очень кстати.

Изменить: Или вы можете обновить параметр напрямую (вместо обновления одного из связанных с ним элементов управления) с помощью следующего кода:

Я показываю FontDialog во второй форме. Я не могу получить доступ к управлению первой формой во второй форме. Вам не нужно открывать первую форму - это происходит автоматически. Это код во второй форме! Я только что обнаружил / вспомнил, что вам не нужен этот параметр для каждого элемента управления. Если вы просто привяжете свойство Font формы form к тому же значению ApplicationSetting, это повлияет на все элементы управления в этой форме, если они не переопределили шрифт. Это также, кажется, лучше справляется с размещением элементов управления, когда вы делаете это таким образом. Если вы выберете крупный шрифт, он автоматически изменит положение элементов управления. Кстати, после того, как вы создали этот параметр, вы можете увидеть его в списке всех настроек приложения, открыв «Settings.settings» в папке «Свойства» проекта. Только что заметил, что вы также можете напрямую редактировать настройки, что может быть более понятным при чтении кода. Я добавил к своему ответу правку, чтобы продемонстрировать, как это сделать.

Насколько я понимаю, вы хотите установить шрифт для всех элементов управления в форме в загрузке формы.

Читайте также: