最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - Add label in run-time using Controls.Add() in a 'for' loop - Stack Overflow

programmeradmin5浏览0评论

So I am trying to add labels to count things in order on a C# Winform. The code is like this:

private void button2_Click(object sender, EventArgs e)
{
    Label[] labels = new Label[n];
    string[] coor;
    for (int i = 1; i <= coorList.Length; i = i + 2)
    {
        coor = coorList[i].Split(',');
        Coordinate_offset(Int32.Parse(coor[0]), Int32.Parse(coor[1]));
        int j = i - 1;
        labels[j] = new Label();
        labels[j].Text = coorList[i - 1];
        labels[j].Left = codeCoor_x;
        labels[j].Top = codeCoor_y;
        labels[j].ForeColor = System.Drawing.Color.Red;
        labels[j].Font = new Font("Arial", 20, FontStyle.Regular);
        labels[j].BringToFront();
        this.Controls.Add(labels[j]);                
   }
}

Basically, I have this string of coordinate of stuffs on a picture, and I want to add "order numbering" on top of stuffs on that picture when I press a button.

Now this kinda works. The only problem is when I press the button for the first time, the program always skips the last label, but every time after that it works just fine.

Also, when I press the button the second time, the previously missing last label also shows up.

I genuinely have no idea how this can happen, so any help/suggestion is appreciated!

Edit: I messed around a bit and figured out that the last label has always been, in fact, right there. But somehow it appears in the back of the image, even though I has used .BringToFront(). I am now beyond confused.

So I am trying to add labels to count things in order on a C# Winform. The code is like this:

private void button2_Click(object sender, EventArgs e)
{
    Label[] labels = new Label[n];
    string[] coor;
    for (int i = 1; i <= coorList.Length; i = i + 2)
    {
        coor = coorList[i].Split(',');
        Coordinate_offset(Int32.Parse(coor[0]), Int32.Parse(coor[1]));
        int j = i - 1;
        labels[j] = new Label();
        labels[j].Text = coorList[i - 1];
        labels[j].Left = codeCoor_x;
        labels[j].Top = codeCoor_y;
        labels[j].ForeColor = System.Drawing.Color.Red;
        labels[j].Font = new Font("Arial", 20, FontStyle.Regular);
        labels[j].BringToFront();
        this.Controls.Add(labels[j]);                
   }
}

Basically, I have this string of coordinate of stuffs on a picture, and I want to add "order numbering" on top of stuffs on that picture when I press a button.

Now this kinda works. The only problem is when I press the button for the first time, the program always skips the last label, but every time after that it works just fine.

Also, when I press the button the second time, the previously missing last label also shows up.

I genuinely have no idea how this can happen, so any help/suggestion is appreciated!

Edit: I messed around a bit and figured out that the last label has always been, in fact, right there. But somehow it appears in the back of the image, even though I has used .BringToFront(). I am now beyond confused.

Share Improve this question edited Mar 7 at 7:48 Uwe Keim 40.8k61 gold badges190 silver badges304 bronze badges asked Mar 7 at 6:58 Nemo4720Nemo4720 33 bronze badges 5
  • 2 It might be useful to think a bit about how BringToFront would work. It needs to affect the order controls are drawn in. And it is a command, i.e. "do this right now", not setting a state. So the command would not do anything before you have added it to the list of controls. – JonasH Commented Mar 7 at 7:26
  • 2 ALso in loop your are doing i = i + 2, and inside the loop, you do j = i - 1, then you are accessing labels array with j. Effectivaly, you are only working with every second label on indexes 0, 2, 4 etc. And if coorList has 6 items, loop would end prematurely, because i = 5 would be last iteration, on next iteration i would be 7, stopping the loop, so last i processed would be 5, meaning last j = 4, so you would miss 5th item. All this together can have very unexpected results IMO, and this code just needs proper debugging. – Michał Turczyn Commented Mar 7 at 8:01
  • 3 Using the debugger on Visual Studio will really help you to understand what your code is really doing. – Steve Commented Mar 7 at 8:44
  • Holy hell thanks guys. I moved the BringToFront function to after adding those labels, and it works wonder. I really misunderstood it lol – Nemo4720 Commented Mar 8 at 9:19
  • @JonasH Maybe you could post your comment as an answer as it seems that solved the issue for OP. – Sal Commented Mar 10 at 14:31
Add a comment  | 

1 Answer 1

Reset to default 0

BringToFront is a command that changes the order of controls, so it is rendered last, and is first to receive any input. But this require the control to be added to some form of collection. If it is run before this.Controls.Add(labels[j]); it will not do anything. So the simple solution is to just move .BringToFront() after the .Add(...).

An alternative approach would be to assign each control a value to determine its order. But winforms does not have much builtin support for this, so the solution is a bit of a hack. Using the "tag" to determine the sort value:

var sortedControls = this.Controls.OfType<Control>().OrderBy(c =>  Convert.ToInt32(c.Tag)).ToList();
this.Controls.Clear();
this.Controls.AddRange(sortedControls);

This would need to be run whenever a control is added, or changes tag.

发布评论

评论列表(0)

  1. 暂无评论