将Winforms控件带到前面

时间:2010-04-11 17:59:37

标签: c# winforms controls

除了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();
    }
}

5 个答案:

答案 0 :(得分:18)

是的,还有另一种方式。 Controls.SetChildIndex()也会更改Z顺序。索引为0的那个是顶部的那个。虽然不会给你买任何东西,BringToFront()使用这种方法。

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

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

答案 1 :(得分:6)

Controls'z-index是每个容器。

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

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

编辑:您的userContainer控件可能落后于另一个控件。

答案 2 :(得分:5)

您是否在Invalidate()之后尝试过BringToFront()? BringToFront不会引发Paint事件

试试这个:

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

答案 3 :(得分:2)

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

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

到此:

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

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

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

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

答案 4 :(得分:0)

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

长话短说:对于一个容器 - 当你想要更改z顺序时,你需要通过更改ALL而不仅仅是某些索引来确保控件具有不同的索引。例如:

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

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