Как управлять разрешением шрифта в приложении .NET WinForms

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

Для всех, кто имеет опыт работы с приложениями winforms, как вы управляете макетом формы, чтобы DPI не влиял на внешний вид приложения?

Вы также можете проверить этот блог по этому поводу, я думаю, он предоставляет хорошую информацию по теме: telerik.com/blogs/…

checho 02.12.2016 17:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
36
2
28 917
3

Ответы 3

Установите AutoScaleMode на Наследовать везде (т.е. все ваши UserControls) с помощью глобального поиска / замены, затем установите AutoScaleMode на Dpi в вашей основной форме.

Я также считаю, что в подобной ситуации контейнеры макета работают лучше, чем якоря.

Это помогло мне справиться с неприятной ситуацией масштабирования DPI с помощью стороннего инструментария пользовательского интерфейса. Спасибо!

pelazem 01.03.2011 21:28

Предполагая, что вы не пытаетесь соблюдать выбор шрифта пользовательского интерфейса (SystemFonts.IconTitleFont) и жестко запрограммировать свои формы только для одного размера шрифта (например, Tahoma 8pt, Microsoft Sans Serif 8.25pt), вы можете установить AutoScaleMode своей формы на ScaleMode.Dpi.

Это приведет к масштабированию размера формы и самый ее дочерних элементов управления на коэффициент CurrentDpiSetting / 96 путем вызова Form.Scale(), который, в свою очередь, рекурсивно вызывает защищенный метод ScaleControl() для себя и всех дочерних элементов управления. ScaleControl увеличит положение элемента управления, его размер, шрифт и т. д. По мере необходимости для нового коэффициента масштабирования.

Warning: Not all controls properly scale themselves. The columns of a listview, for example, will not get wider as the font gets larger. In order to handle that you'll have to manually perform additional scaling as required. i do this by overriding the protected ScaleControl() method, and scaling the listview columns manually:

public class MyForm : Form
{
   protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
   {
      base.ScaleControl(factor, specified);
      Toolkit.ScaleListViewColumns(listView1, factor);
   }
}

public class Toolkit  
{
   /// <summary>
   /// Scale the columns of a listview by the Width scale factor specified in factor
   /// </summary>
   /// <param name = "listview"></param>
   /// <param name = "factor"></param>
   /// <example>/*
   /// protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
   /// {
   ///    base.ScaleControl(factor, specified);
   ///    
   ///    //ListView columns are not automatically scaled with the ListView, so we
   ///    //must do it manually
   ///    Toolkit.ScaleListViewColumns(lvPermissions, factor);
   /// }
   ///</example>
   public static void ScaleListViewColumns(ListView listview, SizeF factor)
   {
      foreach (ColumnHeader column in listview.Columns)
      {
          column.Width = (int)Math.Round(column.Width * factor.Width);
      }
   }
}

Это все хорошо, если вы просто используете элементы управления. Но если вы когда-нибудь будете использовать какие-либо жестко заданные размеры пикселей, вам нужно будет масштабировать ширину и длину пикселей в соответствии с текущим коэффициентом масштабирования формы. Некоторые примеры ситуаций, в которых размеры пикселей могут быть жестко заданы:

  • рисование прямоугольника высотой 25 пикселей
  • рисование изображения в месте (11,56) на форме
  • растянуть рисование иконки до 48x48
  • рисование текста с использованием Microsoft Sans Serif 8.25pt
  • получение значка формата 32x32 и вставка его в PictureBox

В этом случае вам необходимо масштабировать эти жестко запрограммированные значения на «текущий коэффициент масштабирования». К сожалению, «текущий» масштабный коэффициент не указан, нам нужно записать его самим. Решение состоит в том, чтобы предположить, что изначально коэффициент масштабирования равен 1,0, и каждый раз, когда вызывается ScaleControl(), изменяйте текущий коэффициент масштабирования на новый коэффициент.

public class MyForm : Form
{
   private SizeF currentScaleFactor = new SizeF(1f, 1f);

   protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
   {
      base.ScaleControl(factor, specified);

      //Record the running scale factor used
      this.currentScaleFactor = new SizeF(
         this.currentScaleFactor.Width * factor.Width,
         this.currentScaleFactor.Height * factor.Height);

      Toolkit.ScaleListViewColumns(listView1, factor);
   }
}

Изначально коэффициент масштабирования - 1.0. Если форма затем масштабируется с помощью 1.25, коэффициент масштабирования становится следующим:

1.00 * 1.25 = 1.25    //scaling current factor by 125%

Если форма затем масштабируется с помощью 0.95, новый коэффициент масштабирования становится

1.25 * 0.95 = 1.1875  //scaling current factor by 95%

Причина, по которой используется SizeF (а не одно значение с плавающей запятой), заключается в том, что значения масштабирования могут быть разными в направлениях x и y. Если для формы задано значение ScaleMode.Font, она масштабируется до нового размера шрифта. Шрифты могут иметь разное соотношение сторон (напримерSegoe UI - более высокий шрифт, чем Тахома). Это означает, что вам нужно масштабировать значения x и y независимо.

Поэтому, если вы хотите разместить элемент управления в местоположении (11,56), вам придется изменить свой код позиционирования с:

Point pt = new Point(11, 56);
control1.Location = pt;

к

Point pt = new Point(
      (int)Math.Round(11.0*this.scaleFactor.Width),
      (int)Math.Round(56.0*this.scaleFactor.Height));
control1.Location = pt;

То же самое применимо, если вы собирались выбрать размер шрифта:

Font f = new Font("Segoe UI", 8, GraphicsUnit.Point);

должно было стать:

Font f = new Font("Segoe UI", 8.0*this.scaleFactor.Width, GraphicsUnit.Point);

И извлечение значка 32x32 в растровое изображение изменится с:

Image i = new Icon(someIcon, new Size(32, 32)).ToBitmap();

к

Image i = new Icon(someIcon, new Size(
     (int)Math.Round(32.0*this.scaleFactor.Width), 
     (int)Math.Round(32.0*this.scaleFactor.Height))).ToBitmap();

и т.п.

Поддержка нестандартных дисплеев DPI - налог, который должны платить все застройщики. Но то, что никто не хочет, - вот почему Microsoft отказалась и добавила в Vista возможность графической карты расширять любые приложения, которые не говорят, что они должным образом обрабатывают высокое разрешение..

Я знаю, что это несколько радикально, но подумайте о том, чтобы переписать свое приложение в WPF. Приложения WPF выглядят одинаково для всех настроек DPI.

Другие вопросы по теме