将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 )
是计算特定控件索引的方法。