Проблемы AutoScaleMode с измененным стандартным шрифтом

У меня есть некоторые проблемы с Формой. Свойство AutoScaleMode вместе со средствами управления фиксированным размером, при использовании шрифта не по умолчанию. Я свел его к простому тестовому приложению (WinForms 2.0) только с одной формой, некоторыми средствами управления фиксированным размером и следующими свойствами:

class Form1 : Form
{
    // ...
    private void InitializeComponent()
    {
        // ...
        this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
        this.Font = new System.Drawing.Font("Tahoma", 9.25F);
        // ...
    }
}

Менее чем 96 точек на дюйм, Windows XP, форма правильно походит на этот пример на 96 точек на дюйм:

96 dpi WinForm

Менее чем 120 точек на дюйм, Windows XP, функция автомасштабирования Windows Forms производят этот пример на 120 точек на дюйм:

Previous WinForm scaled to 120 dpi

Как Вы видите, групповые блоки, кнопки, список или структурные виды масштабируются правильно, многострочные текстовые поля становятся слишком большими в вертикальной оси, и маркировка фиксированного размера не масштабируется правильно и в вертикальном и в горизонтальном направлении. Кажется, ошибка в платформе.NET?

Править: некоторые подсказки: изменение Шрифта только применяется к содержанию формы, средства управления наследовали свой шрифт от формы. Я хотел бы сохранить это этим путем, если это возможно.

Используя стандартный шрифт (Microsoft Sans Serif 8.25pt), не происходит эта проблема. Используя AutoScaleMode = Font (с соответствующим AutoScaleDimensions, конечно), или не масштабируется вообще или масштабируется точно как замеченный выше, в зависимости от того, когда Шрифт установлен (перед или после изменения AutoScaleMode). Проблема не характерна для Шрифта "Tahoma", она происходит также с Microsoft Sans Serif, 9.25 ПБ.

И да, я уже считал это, ТАК отправьте высокие проблемы DPI, но это действительно не помогает мне.

Какие-либо предложения, как прийти это?

EDIT2: Некоторая дополнительная информация о моем намерении: у Меня есть приблизительно 50 уже рабочих диалоговых окон фиксированного размера с несколькими сотнями правильно помещенных средств управления фиксированным размером. Они были перемещены от более старого C++ платформа GUI к C#/Winforms, вот почему они - весь фиксированный размер. Все они выглядят хорошо с 96 точками на дюйм с помощью шрифта на 9.25 ПБ. Под старой платформой, масштабируясь к 120 точкам на дюйм хорошо работал - все средства управления фиксированным размером, масштабируемые равный по обоим размерам. На прошлой неделе мы обнаружили это странное поведение масштабирования под WinForms при переключении на 120 точек на дюйм. Можно предположить, что большинство наших диалоговых окон теперь выглядит очень плохо менее чем 120 точек на дюйм. Я ищу решение, которое избегает полной модернизации все те диалоговые окна.

EDIT3: Для тестирования этого поведения по моему скромному мнению, это - хорошая идея настроить виртуальную среду Windows XP с 120 точками на дюйм, в то время как среда разработки находится менее чем 96 точек на дюйм (по крайней мере, это - то, что я сделал). Для изменения между 96 и 120 точками на дюйм обычно нужна перезагрузка под Победой XP, иначе Вы не видите то, что действительно происходит.

// As requested: the source code of Form1.cs 
namespace DpiChangeTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Font f = this.textBox1.Font;
        }
    }
}

 // here the source of Form1.Designer.cs:
namespace DpiChangeTest
{
    partial class Form1
    {
        private System.ComponentModel.IContainer components = null;

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Forms Designer generated code

        private void InitializeComponent()
        {
            System.Windows.Forms.ListViewItem listViewItem2 = new System.Windows.Forms.ListViewItem("A list view control");
            System.Windows.Forms.TreeNode treeNode2 = new System.Windows.Forms.TreeNode("A TreeView control");
            this.button1 = new System.Windows.Forms.Button();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.listView1 = new System.Windows.Forms.ListView();
            this.treeView1 = new System.Windows.Forms.TreeView();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(12, 107);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(150, 70);
            this.button1.TabIndex = 0;
            this.button1.Text = "Just a button";
            this.button1.UseVisualStyleBackColor = true;
            // 
            // groupBox1
            // 
            this.groupBox1.Location = new System.Drawing.Point(12, 12);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(150, 70);
            this.groupBox1.TabIndex = 1;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "Just a groupbox";
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(180, 12);
            this.textBox1.Multiline = true;
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(150, 70);
            this.textBox1.TabIndex = 2;
            this.textBox1.Text = "A multiline text box";
            // 
            // label1
            // 
            this.label1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.label1.Location = new System.Drawing.Point(179, 107);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(150, 70);
            this.label1.TabIndex = 3;
            this.label1.Text = "A label with AutoSize=False";
            // 
            // listView1
            // 
            this.listView1.Items.AddRange(new System.Windows.Forms.ListViewItem[] {
            listViewItem2});
            this.listView1.Location = new System.Drawing.Point(12, 201);
            this.listView1.Name = "listView1";
            this.listView1.Size = new System.Drawing.Size(150, 70);
            this.listView1.TabIndex = 4;
            this.listView1.UseCompatibleStateImageBehavior = false;
            // 
            // treeView1
            // 
            this.treeView1.Location = new System.Drawing.Point(179, 201);
            this.treeView1.Name = "treeView1";
            treeNode2.Name = "Knoten0";
            treeNode2.Text = "A TreeView control";
            this.treeView1.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
            treeNode2});
            this.treeView1.Size = new System.Drawing.Size(150, 70);
            this.treeView1.TabIndex = 5;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
            this.ClientSize = new System.Drawing.Size(343, 289);
            this.Controls.Add(this.treeView1);
            this.Controls.Add(this.listView1);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.groupBox1);
            this.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.25F);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.ListView listView1;
        private System.Windows.Forms.TreeView treeView1;
    }
}

 // and Main.cs
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

35
задан 13 revs, 2 users 95% 23 May 2017 в 11:53
поделиться

1 ответ

Наконец-то я нашел ответ на свой вопрос. Короче говоря, эффект не возникает, если установить шрифт каждого элемента управления отдельно, а не устанавливать шрифт содержащей формы. В этом случае функция автоматического масштабирования работает как надо. Интересно, что установка шрифта элементов управления изменяет поведение автомасштабирования, даже если свойство AutoScaleMode установлено в AutoScaleMode.Dpi, а не только когда оно установлено в AutoScaleMode.Font.

В качестве прагматичного решения мы создали небольшую программу командной строки, которая читает файлы designer.cs, проверяет, есть ли у всех элементов управления явное назначение шрифта, и если нет, добавляет назначение во вновь созданную копию кода дизайнера. Мы встроили эту программу в наш набор автоматических тестов, поэтому всякий раз, когда форма получает новые элементы управления или добавляется новая форма, а разработчик забывает добавить явное назначение шрифта, тесты будут провалены. Между делом, у нас это решение работает с того момента, когда я впервые задал этот вопрос (4 года назад), и с тех пор оно несколько раз спасало нас от проблем с масштабированием.

36
ответ дан 27 November 2019 в 15:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: