當使用非默認字體時,Form.AutoScaleMode屬性和固定大小的控件一起出現了一些問題。我煮沸它歸結爲一個簡單的測試應用(的WinForms 2.0)只有一種形式中,一些固定尺寸的控制和以下性質:AutoScaleMode更改默認字體的問題
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);
// ...
}
}
在96DPI時,Windows XP,形式看起來正確地像這樣96 DPI例如:
在120 DPI,Windows XP中,Windows窗體自動縮放功能產生本120 DPI例如:
正如您所看到的,組合框,按鈕,列表或樹視圖正確縮放,多行文本框在垂直軸上變得太大,而固定大小的標籤在垂直和水平方向上都不能正確縮放。似乎是在.NET框架中的錯誤?
編輯:一些提示:字體更改只適用於包含窗體,控件從窗體繼承它們的字體。如果可能,我想保持這種方式。
使用默認字體(Microsoft Sans Serif 8.25pt),不會發生此問題。使用AutoScaleMode = Font
(當然具有足夠的AutoScaleDimensions)根據Font設置的時間(在AutoScaleMode更改之前或之後),根本不會縮放或縮放。該問題不是特定於「Tahoma」字體,它也發生在Microsoft Sans Serif 9.25pt。
是的,我已經讀過這個SO帖子 high DPI problems 但它並沒有真正幫助我。
任何建議如何來解決這個問題?
編輯2:關於我的意圖的一些額外信息:我已經有大約50個工作的固定大小的對話框,有幾百個正確放置的固定大小的控件。他們從舊的C++ GUI框架遷移到C#/ Winforms,這就是爲什麼他們都是固定大小。所有這些都使用9.25pt字體在96 dpi下顯得很好。在舊的框架下,縮放到120 dpi的效果很好 - 所有固定大小的控件在兩個維度上縮放比例相等。上週,我們在切換到120 dpi時在WinForms下檢測到了這種奇怪的縮放行爲。你可以想象,現在我們的大多數對話框在120dpi以下看起來都很糟糕。我正在尋找一種解決方案,避免完全重新設計所有這些對話框。
EDIT3:爲了測試這種行爲,恕我直言,當開發環境位於96 dpi(至少,這就是我所做的)時,建立一個120 dpi的虛擬Windows XP環境是個好主意。通常需要在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());
}
我遇到了同樣的問題。控制不響應'Scale'(或受保護的「ScaleControl」)方法來縮放其'Font'。我正在玩的解決方案是遞歸迭代所有控件,並且(神奇地)確定字體是否應該是什麼,並修復它。儘管如此,我仍然在努力研究一些陷阱。如果我得到解決方案,會報告回來 – 2011-11-24 19:14:36
我感到你的痛苦。我在同一條船上,似乎這是一個普遍而且非常嚴重的問題,但似乎沒有人解決它或提供答案。 – 2012-04-09 18:02:18
@ShacharWeis:對於我們的情況,我們有一個解決方案。我們創建了一個小程序(小於200 LOC),它讀取designer.cs文件,掃描所有控件是否具有明確的字體分配,如果沒有,則將該分配添加到代碼中。 – 2012-04-16 16:11:57