C# 中窗体的 Control 属性中的控件顺序

Posted

技术标签:

【中文标题】C# 中窗体的 Control 属性中的控件顺序【英文标题】:Order of controls in a form's Control property in C# 【发布时间】:2010-09-21 18:49:03 【问题描述】:

我在将 FlowLayoutPanel 添加到表单的 controls 属性中的顺序方面遇到了一个特殊问题。这是我尝试过的,

我在 C# 窗口应用程序中添加了 7 个 FlowLayoutPanel,从左到右以垂直条状排列。然后我再次从左到右将流布局标记为 1、2、3、... 7。现在在表单的负载处理程序中,我写了以下sn-p,

    foreach (FlowLayoutPanel aDaysControl in this.Controls)
    
        MessageBox.Show(aDaysControl.Tag.ToString());
    

我希望消息按 1、2、... 7 的顺序显示。但我以相反的顺序得到它(7、6、...1)。有人可以帮我解决我犯的错误吗??

保留订单的原因,

我正在尝试制作日历控件 每行代表一天。如果一个 一个月从星期三开始,然后我 需要添加一个空标签到 第一个(星期一)和第二个(星期二) 排。所以顺序有点重要

【问题讨论】:

您在我的回答中评论说订单对您很重要。我很想知道为什么。你能编辑你的问题来解释原因吗?谢谢。 【参考方案1】:

如果将来有其他设计师移除控件、添加回控件等怎么办?检查设计师总是一团糟。更好的是在枚举之前对容器控件中的控件进行排序。我使用这个扩展方法(如果你有 Linq):

public static List<Control> ToControlsSorted(this Control panel)

    var controls = panel.Controls.OfType<Control>().ToList();
    controls.Sort((c1, c2) => c1.TabIndex.CompareTo(c2.TabIndex));
    return controls;

你可以:

foreach (FlowLayoutPanel aDaysControl in this.ToControlsSorted())

    MessageBox.Show(aDaysControl.TabIndex.ToString());

(以上为TabIndex)。根据Tag 排序将是微不足道的。

【讨论】:

【参考方案2】:

我知道这是一个很老的问题,但是...

您可能想使用SetChildIndex。例如this.Controls.SetChildIndex(button1, 0);

【讨论】:

【参考方案3】:

真的有问题吗?

只要 UI 运行正常(例如,按 Tab 键顺序),我建议您不要对枚举顺序做出任何假设。

编辑:感谢您更详细地解释您的要求。我想我仍然建议不要使用它们存储在 Controls 集合中的顺序。最好将这些实现细节视为“不透明”。您有一个与每个控件关联的标签,因此您可以使用它来识别正确的控件。为了加快处理速度,您可以构建一个按序号引用控件的 7 元素数组:

FlowLayoutPanel[] panels = new FlowLayoutPanel[7];

foreach(FlowLayoutPanel panel in this.Controls)

    panels[(int)panel.Tag] = panel;


// Now, you can reference the panels directly by subscript:

panels[2].BackColor = Color.Aquamarine;

虽然我会进行一些类型检查以使这段代码更加健壮!

【讨论】:

但是顺序确实_对我来说很重要!!【参考方案4】:

如果您查看由设计器 Form1.designer.cs 生成的代码,它将看起来像这样:

        // 
        // Form1
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(658, 160);
        this.Controls.Add(this.flowLayoutPanel7);
        this.Controls.Add(this.flowLayoutPanel6);
        this.Controls.Add(this.flowLayoutPanel5);
        this.Controls.Add(this.flowLayoutPanel4);
        this.Controls.Add(this.flowLayoutPanel3);
        this.Controls.Add(this.flowLayoutPanel2);
        this.Controls.Add(this.flowLayoutPanel1);
        this.Name = "Form1";
        this.Text = "Form1";
        this.ResumeLayout(false);

请注意它是如何构建的,您首先添加了面板 1,然后添加了 2,依此类推。 但随着代码运行,它会先添加 7,然后添加 6。

此代码将在设计器生成的 InitializeComponent() 函数中。

为什么需要它们按特定顺序运行?

我不会依赖设计师来保持你想要的顺序。我会自己对控件进行排序:

        var flowpanelinOrder = from n in this.Controls.Cast<Control>()
                               where n is FlowLayoutPanel
                               orderby int.Parse(n.Tag.ToString())
                               select n;

        /* non linq
        List<Control> flowpanelinOrder = new List<Control>();
        foreach (Control c in this.Controls)
        
            if (c is FlowLayoutPanel) flowpanelinOrder.Add(c);                
        
        flowpanelinOrder.Sort();
         * */

        foreach (FlowLayoutPanel aDaysControl in flowpanelinOrder)
        
            MessageBox.Show(aDaysControl.Tag.ToString());
        

【讨论】:

我正在尝试制作一个日历控件,每行代表一天。如果一个月从周三开始,那么我需要在第一行(周一)和第二行(周二)添加一个空标签。所以顺序有点重要。 嗯。我有点懒。立即学习。【参考方案5】:

在 yourForm.designer.cs 中查看它们添加到表单中的顺序

【讨论】:

是的。就是那个问题。它们以相反的方式添加。不知道为什么。谢谢

以上是关于C# 中窗体的 Control 属性中的控件顺序的主要内容,如果未能解决你的问题,请参考以下文章

c#中 在不同窗体中根据控件id或者name属性查找另一个窗体里的控件

C#界面里control.ForeColor 和 control.BackColor 属性的使用

C#界面里control.ForeColor 和 control.BackColor 属性的使用

C# WinForm 透明控件 PictureBox透明

C#如何让控件一直在窗体中间显示

C# WinForm窗体 控件Control 的 InvalidateUpdateRefresh的区别