Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 更改默认字体后的自动缩放模式问题_C#_.net_Winforms - Fatal编程技术网

C# 更改默认字体后的自动缩放模式问题

C# 更改默认字体后的自动缩放模式问题,c#,.net,winforms,C#,.net,Winforms,在使用非默认字体时,Form.AutoScaleMode属性和固定大小控件存在一些问题。我将其归结为一个简单的测试应用程序(WinForms 2.0),只有一个表单、一些固定大小的控件和以下属性: class Form1 : Form { // ... private void InitializeComponent() { // ... this.AutoScaleDimensions = new System.Drawing.SizeF

在使用非默认字体时,Form.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 dpi、Windows XP下,表单看起来与此96 dpi示例完全相同:

在120 dpi、Windows XP下,Windows窗体自动缩放功能生成以下120 dpi示例:

如您所见,组框、按钮、列表或树视图的缩放正确,多行文本框在纵轴上过大,固定大小的标签在垂直和水平方向上都无法正确缩放。似乎是.NET框架中的bug

编辑:一些提示:字体更改仅应用于包含表单,控件从表单继承其字体。如果可能的话,我想保持这种状态

使用默认字体(Microsoft Sans Serif 8.25pt),不会出现此问题。使用
AutoScaleMode=Font
(当然,使用足够的AutoScaleDimensions)要么根本无法缩放,要么完全按照上面所示进行缩放,这取决于字体设置的时间(在更改AutoScaleMode之前或之后)。这个问题并不特定于“Tahoma”字体,它也发生在Microsoft Sans Serif 9.25pt上

是的,我已经读过这篇文章了 但这并不能真正帮助我

有什么建议可以解决这个问题吗

EDIT2:关于我的意图的一些附加信息:我已经有大约50个固定大小的对话框,其中有数百个正确放置的固定大小控件。它们从一个更古老的C++ GUI框架迁移到C/y/WrFrm,这就是它们都是固定大小的原因。使用9.25pt字体的96 dpi,所有这些都看起来不错。在旧的框架下,缩放到120 dpi效果很好-所有固定大小的控件在两个维度上缩放相等。上周,当切换到120 dpi时,我们在WinForms下检测到这种奇怪的缩放行为。您可以想象,在120 dpi下,我们的大多数对话现在看起来非常糟糕。我正在寻找一个解决方案,避免完全重新设计所有这些对话框

EDIT3:为了测试这种行为,IMHO最好设置一个120 dpi的虚拟Windows XP环境,而开发环境驻留在96 dpi以下(至少,我是这么做的)。在Win XP下,在96到120 dpi之间切换通常需要重新启动,否则您看不到真正发生的情况

// 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());
    }

我终于找到了我问题的答案。简而言之,当单独设置每个控件的字体而不是设置包含表单的字体时,不会产生这种效果。这样,自动缩放功能就可以正常工作。有趣的是,设置控件的字体会更改自动缩放行为,即使AutoScaleMode属性设置为
AutoScaleMode.Dpi
,而不仅仅是设置为
AutoScaleMode.font


作为一个实用的解决方案,我们创建了一个小的命令行程序,它读取designer.cs文件,扫描所有控件是否具有显式字体分配,如果没有,则将分配添加到新创建的designer代码副本中。我们将这个程序嵌入到我们的自动测试套件中,因此每当一个表单获得新控件,或者添加了新表单,而开发人员忘记添加显式字体分配时,测试就会失败。在这两者之间,从我第一次提出这个问题(4年前)起,我们就有了这个解决方案,从那时起,它使我们多次避免了扩展问题。

我在VS 2008上使用compact framework 3.5解决了类似的问题。在我的例子中,我有一个tabcontrol,每个tabpage都有一个面板,所有选项卡都被固定到它们的父级。每个面板都包含多个标签和文本框控件,因此,当用户打开SIP(软输入面板/键盘)时,滚动条将显示在右侧,文本框控件将缩放宽度,以避免绘制额外的水平滚动条

我最初的尝试是将表单的自动缩放模式设置为dpi,将每个tabpages的autoscroll属性设置为true,将每个面板的autoscroll属性设置为true。每个标签定位到顶部、左侧,每个文本框控件定位到左侧、顶部、右侧。表单是在designer中创建的,屏幕宽度为240像素,当在480像素屏幕宽度的vga设备上运行时,文本框将在右侧绘制足够容纳2个滚动条的空间(可能一个用于tabpage,一个用于panel),即使滚动条没有出现。当激活SIP时,行为是正确的,所有的文本框都调整了大小,但在文本框右侧和滚动条之间仍然有大约40像素的死区

我只需将面板的autoscroll属性设置为false,然后在激活SIP时将其设置为true,就可以解决这个问题。这样可以自动调整屏幕的全宽(像素宽度),并在激活或取消激活滚动条时动态调整文本框控件的大小


作为补充说明,compact framework(3.5)没有字体自动缩放模式(只有none、dpi和inherit),但我尝试按照原作者的建议重置每个文本框控件的字体,但这对控件的自动缩放没有任何影响。

我也发现这种行为很奇怪,在尝试根据大小或分辨率的变化自动缩放应用程序中的控件(及其相关字体)时,我也遇到了类似的难题

值得一提的是,以下是我一直试图应用手动修复的简要概述:

首先,在应用程序启动时,我通过访问Screen::PrimaryScreen属性中的Bounds成员来捕获用户的系统分辨率,并根据需要以编程方式调整表单大小
 this.SuspendLayout();
 this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; // Font in this case
 this.Font = new Font(....); // set your new font
 this.ResumeLayout();
this.Label1.Font = this.Font;
this.MultiLineTextbox.Font = this.Font;