0

Well, I have this code, it works properly if I use for loop over foreach loop. I try to change background and foreground colors for all Labels on form using foreach to process every control. In foreach I've made a condition that determines if control in current iteration is Label and if that's true it will change color.

The problem is foreach runs over every Control on form but if I add condition and any action in it, this foreach will count 22 Labels on form but I have 44 labels over the picturebox.

If I add for loop or while loop, it will start foreach many times and all Labels will be painted. Is that right way to paint all Labels using loops? See the code below:

        /// <summary>
        /// Changes background color of each label on form 
        /// to transparent and foreground color to white.
        /// </summary>
        public void PaintLabels()
        {
            foreach (Control c in this.Controls)
            {
                if (c.GetType() == typeof(Label))
                {              
                    c.Parent = Map;
                    c.BackColor = Color.Transparent;
                    c.ForeColor = Color.White;
                }
            }
        }

The problem is if I don't add for loop around that foreach, this code will work only with 22 Labels on form though condition doesn't say about that. So I need to use for loop with counter from 0 to 6 to force this code to work correctly, but I think that's bad practice and want to find correct solution for this task. Why that foreach does not pick all child items on a single iteration?


Standalone MRE for LinqPad (or just console app)

var control = new Form();
var group = new GroupBox();
control.Controls.Add(group);
var Map = new GroupBox();
control.Controls.Add(Map);
foreach (var element in Enumerable.Range(0, 10))
{
    group.Controls.Add(new Label() { Text = element.ToString() });
}

foreach (Control c in group.Controls)
{
        c.Parent = Map;
        Console.WriteLine(c.Text); // 0 2 4 8 instead of 0 1 2 ... 9
}
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
WideWood
  • 549
  • 5
  • 13
  • This is from here: https://www.c-sharpcorner.com/blogs/how-to-make-a-transparent-label-over-a-picturebox1 Because I have picturebox on form – WideWood Oct 27 '21 at 02:13
  • 2
    `foreach` works fine, and your `for` loop makes no sense. Why would you think you need to run the `foreach` 6 times for it to work? It either works the first time, or it doesn't work at all - you don't use `i` inside the `for` loop at all, so you're just (ridiculously) running the **same exact code** multiple times for absolutely no reason. – Ken White Oct 27 '21 at 02:14
  • If I don't use for loop, this code will paint only 22 Labels but I need 44 Labels to be printed – WideWood Oct 27 '21 at 02:15
  • And if I do loop from 0 to 2 for example, it will paint 30 Labels – WideWood Oct 27 '21 at 02:16
  • @AlexeiLevenkov: OP's code makes no sense, and there's no clear indication of what they are trying to do. I agree with `c.Parent = Map` in the loop looking suspicious. OP should [edit] the post and explain what exactly they are trying to do, because this sounds very much like an XY problem at this point. – Ken White Oct 27 '21 at 02:29
  • Ok I will explain what I wanna do – WideWood Oct 27 '21 at 02:30
  • @KenWhite I edited it and explained what I mean – WideWood Oct 27 '21 at 02:42
  • You still have not provided a [mre] as has been requested. – Ken White Oct 27 '21 at 02:43
  • @KenWhite well how about that? – WideWood Oct 27 '21 at 02:52
  • Still not a [mre]. Did you actually read the linked post? – Ken White Oct 27 '21 at 02:53
  • Why are you doing this: `c.Parent = Map;`? And, do you have all the **44 labels** in the same container? – dr.null Oct 27 '21 at 02:54
  • Of course I did and I tested my code and tried other things. Also I looked for it on the Internet. I removed extra parts of code – WideWood Oct 27 '21 at 02:56
  • @dr.null because I want to paint Labels, these Labels are over the picturebox on form. I found this page to do it: https://www.c-sharpcorner.com/blogs/how-to-make-a-transparent-label-over-a-picturebox1 and also never mind how many labels I have, I could generate it in code or just create in Designer – WideWood Oct 27 '21 at 02:58
  • Loop to set the `Parent` and `BackColor` properties just once in the constructor if these properties don't change. `foreach (Control c in this.Controls.OfType – dr.null Oct 27 '21 at 03:11
  • @AlexeiLevenkov many thanks – WideWood Oct 27 '21 at 03:22
  • Missing part in my last comment: _In the PaintLabels method, loop the **Map.Controls** collection to set the labels ForeColor property._ Just like your other question. – dr.null Oct 27 '21 at 05:04
  • @dr.null yep thank you so much – WideWood Oct 27 '21 at 05:07

1 Answers1

0

First of all thanks to everyone who posted answer and comments. Now I get it and wrote code to solve my problem. I needed to find all controls on form and store it in List I used foreach iteration for that. After that I changed parent of every element in the list using for loop and then called next method to paint all these labels. See the code of solution:

        /// <summary>
        /// Changes parent of Labels on form. Stores all Labels in list 
        /// and then changes parent of each Label that is stored in list
        /// </summary>
        public void ChangeParent()
        {
            List<Control> list = new List<Control>();
            foreach (Control c in this.Controls)
            {
                if (c.GetType() == typeof(Label))
                {
                    list.Add(c);
                }
            }
            for (int i = 0; i < list.Count(); i++)
            {
                list[i].Parent = this.Map;
            }
        }

        /// <summary>
        /// Changes background color of each label on Map picturebox to transparent and foreground color to white.
        /// For first and last labels it defines different colors
        /// </summary>
        public void PaintLabels()
        {  
            //Loop iterates every control whose parent is Map on this form
            foreach (Control c in this.Map.Controls) 
            {
                if (c.GetType() == typeof(Label))
                {    
                    c.BackColor = Color.Transparent;
                    c.ForeColor = Color.White;
                    if (c.Text == "1")
                    {
                        c.ForeColor = Color.Aqua;
                    }
                    if (c.Text == "44")
                    {
                        c.ForeColor = Color.Red;
                    }
                }
            }
        }
WideWood
  • 549
  • 5
  • 13