AutoScaleMode.Font и динамически добавленные элементы управления
У меня были некоторые проблемы с масштабированием элементов управления в моем приложении должным образом с размером шрифта формы. Проблема в том, что форма динамически добавляет элементы управления в ответ на действия пользователя. Любые элементы управления, которые находятся в форме, когда размер шрифта изначально установлен идеально, масштабируются, но добавленные впоследствии имеют проблемы. Их шрифт правильно масштабируется, а их положение и размер - нет. Чтобы увидеть это в действии, создайте простой проект с пустой формой и вставьте следующий код:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
SplitContainer split = new SplitContainer();
split.Dock = DockStyle.Fill;
this.Controls.Add(split);
// Group 1
split.Panel1.Controls.Add(NewGroup());
this.Font = new Font(this.Font.FontFamily, this.Font.Size * 2);
// Group 2
split.Panel2.Controls.Add(NewGroup());
split.SplitterDistance = this.Width / 2;
}
public GroupBox NewGroup()
{
GroupBox groupBox = new GroupBox();
groupBox.Size = new System.Drawing.Size(132, 92);
groupBox.Text = "groupBox";
groupBox.SuspendLayout();
Label label = new Label();
label.AutoSize = true;
label.Location = new Point(6, 16);
label.Text = "label";
groupBox.Controls.Add(label);
Button button = new Button();
button.Location = new Point(6, 58);
button.Size = new Size(93, 28);
button.Text = "button";
groupBox.Controls.Add(button);
CheckBox checkBox = new CheckBox();
checkBox.AutoSize = true;
checkBox.Location = new Point(47, 16);
checkBox.Text = "checkBox";
groupBox.Controls.Add(checkBox);
TextBox textBox = new TextBox();
textBox.Location = new Point(6, 34);
textBox.Size = new Size(120, 20);
textBox.Text = "text";
groupBox.Controls.Add(textBox);
groupBox.ResumeLayout();
return groupBox;
}
}
Вы можете увидеть эффект, о котором я говорю, во втором добавленном групповом окне. Что я могу сделать, чтобы добавить элементы управления после первоначального изменения размера для правильного масштабирования?
ОБНОВИТЬ
Если я изменю второй NewGroup
позвоните, чтобы выглядеть так:
GroupBox group = NewGroup();
split.Panel2.Controls.Add(group);
group.Scale(new SizeF(2.0f, 2.0f));
Результат почти верен. Во многих случаях он имеет тенденцию к отключению на один или два пикселя, и в сложных формах это начинает проявляться гораздо заметнее. Мне действительно нужно, чтобы масштабирование было как можно более согласованным между элементами управления, поэтому я бы хотел избежать такого подхода.
2 ответа
Проблема в том, что вызов AutoScaleMode=AutoScaleMode.Font должен произойти ПОСЛЕ того, как все элементы управления были размещены в форме. Все элементы управления, которые вы размещаете после установки AutoScaleMode, игнорируются при автоматическом масштабировании. Обычно конструктор помещает настройку автомасштабирования в метод InitializeComponents (), поэтому все элементы управления, созданные после метода InitializeComponents (), попадают в категорию игнорируемых. Просто удалите строку из метода InitializeComponents()- и замените ее в конце конструктора форм.
(даже вопрос старый, ответ может помочь другим)
Я думаю, что вы должны сделать это - используйте Graphics.DpiX и Graphics.DpiY, чтобы получить текущий dpi, а затем разделите его на ваш dpi по умолчанию (обычно это 96) и умножьте значения позиции и размера для ваших динамически добавленных элементов управления, которые не отображаются прямо с этим соотношением.