Я создал приложение для малого бизнеса. Некоторые сотрудники в офисе не могут правильно видеть форму. Причина в том, что для них установлено значение DPI выше 96 точек на дюйм. Кто-нибудь знает, как это контролировать?
Для всех, кто имеет опыт работы с приложениями winforms, как вы управляете макетом формы, чтобы DPI не влиял на внешний вид приложения?
Вы также можете проверить этот блог по этому поводу, я думаю, он предоставляет хорошую информацию по теме: telerik.com/blogs/…





Установите AutoScaleMode на Наследовать везде (т.е. все ваши UserControls) с помощью глобального поиска / замены, затем установите AutoScaleMode на Dpi в вашей основной форме.
Я также считаю, что в подобной ситуации контейнеры макета работают лучше, чем якоря.
Это помогло мне справиться с неприятной ситуацией масштабирования DPI с помощью стороннего инструментария пользовательского интерфейса. Спасибо!
Предполагая, что вы не пытаетесь соблюдать выбор шрифта пользовательского интерфейса (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); } } }
Это все хорошо, если вы просто используете элементы управления. Но если вы когда-нибудь будете использовать какие-либо жестко заданные размеры пикселей, вам нужно будет масштабировать ширину и длину пикселей в соответствии с текущим коэффициентом масштабирования формы. Некоторые примеры ситуаций, в которых размеры пикселей могут быть жестко заданы:
В этом случае вам необходимо масштабировать эти жестко запрограммированные значения на «текущий коэффициент масштабирования». К сожалению, «текущий» масштабный коэффициент не указан, нам нужно записать его самим. Решение состоит в том, чтобы предположить, что изначально коэффициент масштабирования равен 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.
возможный дубликат Как написать код WinForms, который автоматически масштабируется до системного шрифта и настроек dpi?