2015-03-15 3 views
1

Мне нужно добавить программные средства управления в пользовательский элемент управления и разместить их в определенном макете. Я думал, что будет достаточно легко создать реплика во время разработки внутри панели, а затем использовать сгенерированный код для их создания на другой панели во время выполнения.Управление позициями 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

RunTime управления Код:

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); 

    } 
+1

Ваша первоначальная форма была создана на компьютере с разрешением 144 dpi (150% в апплете дисплея). Но ваша программа не [dpiAware] (http://stackoverflow.com/a/13228495/17034) или работает на компьютере с разрешением 96 точек на дюйм, поэтому размеры, которые вы используете, на 150% слишком велики. –

ответ

2

Ваша проблема с Autoscaling.

Этот код:

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

не может означать, что this.dateTimePicker1.Size действительно 219 х 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 (по умолчанию 100% масштабирование в Windows). Вот почему я попросил записать ваше значение, чтобы вы могли использовать его.

Если вы все еще не находите это неприятным, вы также можете прочитать этот вопрос, который содержит дополнительную информацию: Creating a DPI-Aware Application.

Важное примечание я забыл упомянуть, что-то - если вы работаете в команде с программным обеспечением управления источником, проявлять особую осторожность, потому что всякий раз, когда вы что-то сохранить в конструкторе собирается изменить каждый Size и Location, чтобы соответствовать вашей собственной настройки (как объяснялось выше). Это не должно вызывать проблем, но вы должны всегда знать об этом.

+0

Решение, часть 2 не работает. В частности, установка 'AutoScaleDimensions', кажется, не имеет эффекта, если вы сначала не вызвали' SuspendLayout'. Похоже, правильная операция: 'SuspendLayout', установить« AutoScaleDimensions »в измерения времени разработки, отредактировать позиции/размеры управления, затем« ResumeLayout ». – Mark

0

попробуйте изменить

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

в

this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; 
Смежные вопросы