Winforms控件定位

时间:2015-03-15 17:32:33

标签: c# winforms

我需要以编程方式将控件添加到自定义控件并将它们放置在某个布局中。我认为在设计时在面板内创建副本然后使用生成的代码在运行时在另一个面板中构建副本是很容易的。

宽度,高度和宽度等尺寸。大小在运行时间与设计时间之间没有按预期工作。这是为什么?

例如,下面有2个设计时间面板。左侧面板包含设计时控件和右运行控件上的控件。 this.dateTimePicker1.Size = new System.Drawing.Size(219, 26);设置宽度= 219

但是,在运行时dtp2.Size = new System.Drawing.Size(219, 26);太长,我必须使用dtp1.Width = 150;。为什么150而不是219?

enter image description here

运行时控制代码:

    private void BuildControls()
    {

        // 
        // dateTimePicker1
        // 
        DateTimePicker dtp1 = new DateTimePicker();
        dtp1.Location = new System.Drawing.Point(21, 35);
        dtp1.Name = "dateTimePicker1";
        //dtp1.Size = new System.Drawing.Size(219, 26);
        dtp1.Width = 150; //Not 219 as expected?
        dtp1.TabIndex = 1;
        panel2.Controls.Add(dtp1);

        // dateTimePicker2
        // 
        DateTimePicker dtp2 = new DateTimePicker();
        dtp2.Location = new System.Drawing.Point(21, 108);
        dtp2.Name = "dateTimePicker2"; 
        dtp2.Size = new System.Drawing.Size(219, 26); //Copying design time is too wide
        //dtp1.Width = 150;
        dtp2.TabIndex = 2;
        panel2.Controls.Add(dtp2);
    }

DesignTime控制代码:

    private void InitializeComponent()
    {
        this.panel1 = new System.Windows.Forms.Panel();
        this.label1 = new System.Windows.Forms.Label();
        this.dateTimePicker1 = new System.Windows.Forms.DateTimePicker();
        this.dateTimePicker2 = new System.Windows.Forms.DateTimePicker();
        this.label2 = new System.Windows.Forms.Label();
        this.panel2 = new System.Windows.Forms.Panel();
        this.panel1.SuspendLayout();
        this.SuspendLayout();
        // 
        // panel1
        // 
        this.panel1.Controls.Add(this.dateTimePicker2);
        this.panel1.Controls.Add(this.label2);
        this.panel1.Controls.Add(this.dateTimePicker1);
        this.panel1.Controls.Add(this.label1);
        this.panel1.Location = new System.Drawing.Point(26, 36);
        this.panel1.Name = "panel1";
        this.panel1.Size = new System.Drawing.Size(288, 514);
        this.panel1.TabIndex = 0;
        // 
        // label1
        // 
        this.label1.AutoSize = true;
        this.label1.Location = new System.Drawing.Point(17, 21);
        this.label1.Name = "label1";
        this.label1.Size = new System.Drawing.Size(87, 20);
        this.label1.TabIndex = 0;
        this.label1.Text = "Start Date:";
        // 
        // dateTimePicker1
        // 
        this.dateTimePicker1.Location = new System.Drawing.Point(21, 44);
        this.dateTimePicker1.Name = "dateTimePicker1";
        this.dateTimePicker1.Size = new System.Drawing.Size(219, 26);
        this.dateTimePicker1.TabIndex = 1;
        // 
        // dateTimePicker2
        // 
        this.dateTimePicker2.Location = new System.Drawing.Point(21, 108);
        this.dateTimePicker2.Name = "dateTimePicker2";
        this.dateTimePicker2.Size = new System.Drawing.Size(219, 26);
        this.dateTimePicker2.TabIndex = 3;
        // 
        // label2
        // 
        this.label2.AutoSize = true;
        this.label2.Location = new System.Drawing.Point(17, 85);
        this.label2.Name = "label2";
        this.label2.Size = new System.Drawing.Size(81, 20);
        this.label2.TabIndex = 2;
        this.label2.Text = "End Date:";
        // 
        // panel2
        // 
        this.panel2.Location = new System.Drawing.Point(450, 260);
        this.panel2.Name = "panel2";
        this.panel2.Size = new System.Drawing.Size(288, 290);
        this.panel2.TabIndex = 1;
        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(850, 710);
        this.Controls.Add(this.panel2);
        this.Controls.Add(this.panel1);
        this.Name = "Form1";
        this.Text = "Form1";
        this.panel1.ResumeLayout(false);
        this.panel1.PerformLayout();
        this.ResumeLayout(false);

    }

2 个答案:

答案 0 :(得分:3)

您的问题出在Autoscaling

此代码:

this.dateTimePicker1.Size = new System.Drawing.Size(219, 26);

可能并不意味着this.dateTimePicker1.Size真的是219 x 26.为什么?因为这里有这一行,来自.designer.cs:

this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);

在该行之后执行内存中缩放。此缩放在此行之后的所有子控件上执行:

this.groupBox1.PerformLayout();

之后,this.dateTimePicker1.Size将更改为接近150的宽度。您可能还注意到,设计器代码与选择控件时属性窗格中显示的内容不匹配。

解决方案,第1部分

向表单添加内容以在设计器文件中进行更改并保存。这将导致.designer.cs代码与屏幕DPI匹配,您不再看到任何不一致。您的DPI设置似乎高于创建表单时使用的设置 - 如果这是偶然的,请将Windows DPI设置更正为96或100%。

解决方案,第2部分

一旦您的表单设计器与您的屏幕DPI匹配,您将看到所有大小和位置属性都已更改,并且AutoScaleDimensions上设置了新值,请记下此值,因为这是维度匹配您的屏幕DPI。

现在,只要你想要你的控件'尊重屏幕DPI的位置和大小你需要将控制逻辑放在这样的东西:

// Your referential DPI setting (96DPI in this case)
this.AutoScaleDimensions = new SizeF(6F, 13F); 

// TODO: Place your code here

// Setting of your users
this.AutoScaleDimensions = this.CurrentAutoscaleDimensions; 

这会导致放在其间的任何控件缩放到屏幕上当前的DPI。

请注意,6F, 13F是大多数人对96 DPI设置的值(Windows中默认为100%缩放)。这就是为什么我要求记下你的价值,以便你可以使用它。

如果你仍然没有发现这个令人讨厌的话,你也可以阅读这个有额外信息的问题:Creating a DPI-Aware Application

重要提示 我忘记提及一些事情 - 如果你在一个拥有源代码控制软件的团队中工作,请特别小心,因为无论何时你在设计师中保存某些东西,它都会改变每个SizeLocation以匹配你的自己的设置(如上所述)。这不应该导致问题,但你应该始终意识到这一点。

答案 1 :(得分:0)

尝试更改

this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;