foreach控制循环错过了隐藏的控件

时间:2010-07-21 16:15:56

标签: c# forms controls scaling hidden

我目前正在使用的程序使用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();
}

但这并不是一个很好的方法。它可能使应用程序具有明显的闪烁或感知到用户的减速。任何建议都会受到欢迎(包括有关我缩放表格的方法的建议,如果它是一种特别糟糕或不优雅的方式。我偶然发现我当前的方法有点猜测。)

编辑:隐藏控件的可见性通过设计器设置为“False”。它们将在程序的稍后部分通过.Show()函数显示。

再次编辑!:事实证明,可见性甚至不是问题。问题是,只要显示一个控件,它就会在控件集合中的索引周围进行随机播放,所以当我回过头来与它们进行比较时,它们不符合我第一次填充比较时的顺序名单。这意味着一个控件可能会与另一个控件的值进行比较,并最终得到该位置和大小而不是它自己的位置。

2 个答案:

答案 0 :(得分:1)

为什么不使用TableLayoutPanel代替?我认为他们会做你需要的一切,有0行代码。

答案 1 :(得分:0)

如果我理解正确,你的控件会更好anchoring。它们会向上和向下缩放以保持与其包含控件的边缘的距离,并且它们都将由WinForms本身为您处理。