Цикл управления foreach пропускает скрытые элементы управления - PullRequest
0 голосов
/ 21 июля 2010

В программе, над которой я сейчас работаю, используется C # WinForms (в 2.0 .NET Framework, хотя в этом случае это, вероятно, не будет иметь значения). Конструкция требует способности масштабировать форму и все ее элементы управления вверх и вниз. Я сделал это, просматривая каждый из элементов управления, сохраняя их исходные размеры и расположение, и получая их соотношение с исходным размером формы для масштабирования. Это выглядит примерно так:

const int SCALE_W = 600;
const int SCALE_H = 500;

...

if (!listsBuilt){
    foreach (Control c in this.Controls){
        sizes.Add(c.Size);
        positions.Add(c.Location);
    }
    listsBuilt = true;
}

int count = 0;
foreach (Control c in this.Controls){
    c.Height = this.Height * (sizes[count].Height / SCALE_H);
    c.Width = this.Width * (sizes[count].Width / SCALE_W);
    c.Left = this.Width * (positions[count].X / SCALE_W);
    c.Top = this.Height * (positions[count].Y / SCALE_H);
}

Пока это прекрасно работает, и я смог сделать его глобальным и применить его ко всем моим формам. Проблема возникает, когда на форме есть скрытые объекты. Я предполагал, что они все еще будут создаваться, и когда программа впервые зациклилась, чтобы получить исходный размер / позиции объектов, она их подобрала, но это не так. Если я переключаю режимы на форме и показываю некоторые объекты, которых раньше не было, а затем меняю их размер, то объекты оказываются в неправильных местах с неправильными размерами.

Есть ли какой-то способ заставить меня создавать экземпляры скрытых объектов в form_load, даже если они еще не были показаны, поэтому списки будут всегда иметь правильные значения для соответствующих элементов управления? Если бы мне было абсолютно необходимо, я мог бы просто сделать быстрый цикл в начале:

foreach (Control c in this.Controls){
    c.Show();
    c.Hide();
}

но это не очень хороший способ. Это может привести к тому, что приложение будет иметь явное мерцание или ощутимое замедление для пользователя. Любые предложения будут приветствоваться (в том числе предложения, касающиеся метода, с помощью которого я масштабирую форму, если это особенно плохо или не элегантно. Я немного наткнулся на свой текущий метод с небольшой догадкой).

Редактировать: скрытые элементы управления имеют видимость "Ложь" через конструктор. Они отображаются с помощью функции .Show () на более позднем этапе программы.

Edit Again !: Так что получается, что видимость даже не проблема. Скорее всего, проблема заключается в том, что, как только отображается элемент управления, он, кажется, перетасовывает их индекс в коллекции элементов управления, поэтому, когда я возвращаюсь и сравниваю их, они не в том порядке, в котором они были, когда я впервые заполнял сравнение. Список. Это означает, что один элемент управления, скорее всего, будет сравниваться со значениями другого и в конечном итоге получит эту позицию и размер, а не свою собственную.

Ответы [ 2 ]

1 голос
/ 21 июля 2010

Почему бы не использовать TableLayoutPanel вместо этого? Я думаю, что они будут делать все, что вам нужно, с 0 строками кода.

0 голосов
/ 21 июля 2010

Если я вас правильно понимаю, вам будет намного лучше привязать к вашим элементам управления. Они будут увеличиваться и уменьшаться для поддержания расстояния от краев содержащего их элемента управления, и все это будет обрабатываться для вас самой WinForms.

...