C#中表单的Control属性中的控件顺序

我对FlowLayoutPanels添加到表单的controls属性的顺序有一个特殊的问题。 这是我试过的,

我在垂直条带中从左到右添加了7个FlowLayoutPanel到C#窗口应用程序。 然后我再次从左到右标记流量布局为1,2,3,… 7。 现在在表单的加载处理程序中,我编写了以下代码段,

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

我希望消息以1,2,… 7的顺序出现。 但我按相反的顺序得到它(7,6,……)。 有人可以帮我解决我做的错误吗?

保留订单背后的原因,

我正在尝试使用代表一天的每一行进行日历控制。 如果一个月从星期三开始,那么我需要在第一行(星期一)和第二行(星期二)添加一个空标签。 所以顺序有点重要

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

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

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

如果你看看设计师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() where n is FlowLayoutPanel orderby int.Parse(n.Tag.ToString()) select n; /* non linq List flowpanelinOrder = new List(); 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()); } 

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

 public static List ToControlsSorted(this Control panel) { var controls = panel.Controls.OfType().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从那里排序是微不足道的。

这真的是个问题吗?

只要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; 

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