【问题标题】:foreach Control loop misses hidden controlsforeach 控制循环错过了隐藏的控件
【发布时间】:2010-07-21 16:15:56
【问题描述】:

我目前正在开发的程序使用 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() 函数显示。

再次编辑!:事实证明,可见性甚至不是问题。问题在于,一旦显示控件,它似乎会在控件集合中围绕它们的索引进行洗牌,因此当我返回并与它们进行比较时,它们的顺序与我第一次填充比较时的顺序不同列表。这意味着一个控件可能会与另一个控件的值进行比较,并最终得到那个位置和大小,而不是它自己的。

【问题讨论】:

  • 也许我不明白你的问题,但是使用 Anchor 和 Dock 属性而不是编写代码怎么样?
  • 您是否将这些隐藏控件添加到“this”?
  • @sm Anchor and dock 仅用于重新定位代码。我还需要重新调整控件的大小(在我现在拥有的工作版本中,它们会这样做)。
  • 他们有吗?我已经将控件固定在相对的两侧,并且它们按预期调整了大小。
  • @Kawa:如果你将它们锚定在相反的两侧,它们可能会扩展,但根据我的经验(我一开始就这样做了,并决定我不喜欢结果)它并不总是有效出色地。尤其是当你像我一样使用非标准控件时,它们有一堆不同的部分,不能像这样很好地缩放在一起。

标签: c# forms controls scaling hidden


【解决方案1】:

为什么不改用TableLayoutPanel?我认为他们会用 0 行代码完成您需要的一切。

【讨论】:

  • TableLayoutPanel 是否也会调整控件的大小以及重新定位它们?
  • 是的 - 将 TableLayoutPanel 停靠在您的主表单中,然后根据需要创建任意数量的行/列。控件可以跨越多个具有各自Span 属性的行/列。然后将控件锚定到您希望它们调整大小的单元格的侧面。例如,要有 4 个按钮,每个按钮占据屏幕的四分之一,制作一个 2x2 TableLayoutPanel,在每个按钮中放置一个按钮,并将每个按钮锚定到所有四个侧面。
  • 另外,请务必将所有行和列设置为百分比,而不是绝对大小。 (在“编辑行/列”对话框中。)有关更多详细信息和示例,请参阅 msdn.microsoft.com/en-us/library/…。这是一个很棒的布局工具。
【解决方案2】:

如果我对您的理解正确,您最好使用anchoring 您的控件。它们会放大和缩小以保持与包含控件边缘的距离,这一切都将由 WinForms 自己处理。

【讨论】:

  • 我不认为锚定是 OP 想要的;锚定保持控件边缘与其父级之间的绝对距离,而他们正在寻找相对距离。
  • @Daniel Rasmussen:没错。正如我现在所拥有的那样,控件的大小随着表单的大小而放大和缩小,并与表单本身和彼此保持相同的相对距离和比率。实际上,我很早就尝试使用 Anchor/Dock 进行一些缩放,但它与我正在使用的一些非标准 National Instrument 控件配合得不好。
  • @KChaloux 刚刚尝试自己重现您的问题,我在表单加载时获取所有控件的数据,无论它们是可见的、隐藏的还是不可见的。您能否更新您的问题以显示您如何隐藏控件?它们还在控件集合中,对吧?
  • 我认为这实际上是问题的主要部分。它们不在控件集合中,直到在代码中的某个位置明确地获得“.Show()”n。代码中的某处。他们从设计器中的 Visible 属性“false”开始。
  • @KChaloux 在我刚刚编写的测试应用程序中(通过将控件从工具箱拖到表单上并使用属性检查器设置可见性)设计器生成的代码将控件放入集合和循环中正确拉出所有正确的尺寸和位置。如果您的控件不在其父控件的集合中,那么我假设您正在以某种方式控制添加?
猜你喜欢
  • 2023-03-12
  • 2014-08-08
  • 1970-01-01
  • 1970-01-01
  • 2017-07-19
  • 1970-01-01
  • 2012-05-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多