Предполагая, что вы не пытаетесь выполнить выбор шрифта пользовательского интерфейса пользователя (SystemFonts.IconTitleFont) и жестко закодировать свои формы только для одного размера шрифта (например, Tahoma 8pt, Microsoft Sans Serif 8.25pt), вы можете установить * форму От 1001 * до ScaleMode.Dpi
.
Это масштабирует размер формы и большинство ее дочерних элементов управления с коэффициентом CurrentDpiSetting / 96
, вызывая Form.Scale()
, который в свою очередь вызывает защищенный метод ScaleControl()
рекурсивно для себя и для всех дочерние элементы управления. ScaleControl
увеличит позицию, размер, шрифт и т. Д. Элемента управления, необходимые для нового коэффициента масштабирования.
Предупреждение: Не все элементы управления правильно масштабируются. Столбцы
listview, например, не получит
шире, поскольку шрифт становится больше. В
Для того, чтобы справиться с этим вам придется
вручную выполнить дополнительное масштабирование как
требуется. я делаю это, переопределяя
защищенный ScaleControl()
метод и
масштабирование столбцов списка просмотра вручную:
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);
}
}
}
Это все хорошо, если вы просто используете элементы управления. Но если вы когда-либо будете использовать жестко запрограммированные размеры пикселей, вам нужно будет масштабировать ширину и длину ваших пикселей в соответствии с текущим масштабным коэффициентом формы. Некоторые примеры ситуаций, которые могут иметь жестко заданные размеры пикселей:
- рисование прямоугольника высотой 25px
- рисование изображения в месте (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 является более высоким шрифтом, чем Tahoma ). Это означает, что вам необходимо независимо масштабировать значения 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 возможность для графической карты растягивать любые приложения, которые не говорят, что они должным образом обрабатывают высокое разрешение .