将Winforms控件带到前面

除了control.BringToFront()之外还有其他方法可以将控件带到前面吗? 我在用户控件上有一系列标签,当我尝试将其中一个标签放在前面时它无法正常工作。 我甚至已经完成了所有控制并将它们全部发送回去,除了我感兴趣的那个并且它没有改变一件事。

以下是将标签添加到用户控件的方法

private void AddUserLabel() { UserLabel field = new UserLabel(); ++fieldNumber; field.Name = "field" + fieldNumber.ToString(); field.Top = field.FieldTop + fieldNumber; field.Left = field.FieldLeft + fieldNumber; field.Height = field.FieldHeight; field.Width = field.FieldWidth; field.RotationAngle = field.FieldRotation; field.Barcode = field.BarCoded; field.HumanReadable = field.HumanReadable; field.Text = field.FieldText; field.ForeColor = Color.Black; field.MouseDown += new MouseEventHandler(label_MouseDown); field.MouseUp += new MouseEventHandler(label_MouseUp); field.MouseMove += new MouseEventHandler(label_MouseMove); userContainer.Controls.Add(field); SendLabelsToBack(); //Send All labels to back userContainer.Controls[field.FieldName].BringToFront(); } 

这是将所有这些发送到后面的方法。

 private void SendLabelsToBack() { foreach (UserLabel lbl in userContainer.Controls) { lbl.SendToBack(); } } 

是的,还有另一种方式。 Controls.SetChildIndex()也更改Z顺序。 索引为0的那个是顶部的那个。 不买你什么, BringToFront()使用这种方法。

SendLabelsToBack()方法不起作用,它也会发送标签添加到后面。 但是你的下一个声明再次修复了这一点。

好的,这不起作用,这意味着BringToFront()方法不会被执行。 在“输出”窗口中查找“第一次机会exception”通知。 如上所述,如果用户控件包含除UserLabel之外的任何控件,则SendLabelsToBack()将导致exception。 另外,在BringToFront()调用之后设置一个断点并在它断开时检查userContainer.Controls[0].Name的值。

控件的z-index是每个容器。

如果在容器(例如Panel )内的控件上调用BringToFront,则不会将容器放在前面。
因此,控件将仅在该容器中的其他控件之前。

若要查看控件所在的容器,可以使用“视图”菜单中的“文档大纲”窗格。

编辑 :您的userContainer控件可能在不同的控件后面。

你在BringToFront()之后尝试过Invalidate() BringToFront()吗? BringToFront不会引发Paint事件

试试这个:

 private void SendLabelsToBack() { foreach (UserLabel lbl in userContainer.Controls) { lbl.SendToBack(); lbl.Invalidate(); } } 

我想你只需要改变你的最后一行:

 userContainer.Controls[field.FieldName].BringToFront(); 

对此:

 userContainer.Controls[field.Name].BringToFront(); 

当您使用字符串作为Controls集合的索引器时,它将通过控件的Name属性(而不是FieldName属性)。

由于您只是尝试将最近添加的控件添加到顶部,这也可以:

 userContainer.Controls[userContainer.Controls.Count - 1].BringToFront(); 

根据我的经验,看起来像windows将属于一个图形容器(窗格,组框等)的所有控件放在软件集合中。 该集合按子索引排序,子索引是该容器中每个控件的属性。 诀窍是具有相同索引的孩子可以存在并且确实存在。 在这种情况下,Windows将绘制相对于其他人订购的子项,但在它们之间,它将按照与添加到容器中相反的顺序绘制它们。

简而言之:对于一个容器 – 当您想要更改z顺序时,您需要通过更改ALL而不仅仅是某些索引来确保控件具有不同的索引。 例如:

 foreach (Control newControl in TopControl.Controls) { TopControl.Controls.SetChildIndex(newControl,indexlogic(newControl)); } 

其中indexLogic(newControl )是计算特定控件索引的方法。