Предполагая, что вы не пытаетесь соблюдать шрифт пользовательского интерфейса пользователя (SystemFonts.IconTitleFont) и жестко кодируете свои формы только для одного размера шрифта (например, Tahoma 8pt, Microsoft Sans Serif 8.25pt), вы можете установить форму AutoScaleMode
- ScaleMode.Dpi
.
Это будет масштабировать размер формы и наиболее его дочерних элементов на коэффициент CurrentDpiSetting/96
по телефону Form.Scale()
, который в свою очередь вызывает защищенный метод ScaleControl()
recursivly на себя и всех дочерних элементов управления. ScaleControl
увеличит положение, размер, шрифт и т. Д., Если потребуется, для нового коэффициента масштабирования.
Предупреждение: Не все элементы управления должным образом масштабируются. Например, столбцы списка не будут получать ширину по мере увеличения шрифта. В вам необходимо выполнить , чтобы выполнить дополнительное масштабирование, так как требуется . я сделать это путем переопределения метода защищен ScaleControl()
и масштабирования столбцов ListView вручную:
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
If Тхи В этом случае вам необходимо масштабировать эти жестко заданные значения с помощью «масштабного коэффициента масштабирования ». К сожалению, «текущий» масштабный коэффициент не предоставляется, нам нужно самому записать его. Решение состоит в том, чтобы предположить, что изначально коэффициент масштабирования равен 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 дисплеев является tax that all developers should pay. Но тот факт, что никто не хочет, - это то, почему Microsoft gave up and added to Vista the ability for the graphics card to stretch any applications that don't say they properly handle high-dpi.
Возможный дубликат [Как написать код WinForms, который автоматически масштабируется до системных настроек шрифта и dpi?] (Http://stackoverflow.com/questions/22735174/how-to-write-winforms-code-that-auto -scales-to-system-font-and-dpi-settings) – 2015-07-10 11:23:13
Вы также проверяете этот блог на этот вопрос, я думаю, что он содержит хорошую информацию по теме: http://www.telerik.com/blogs/winforms -scaling-at-big-dpi-settings-is-it-even-possible- – checho 2016-12-02 14:16:24