1

I've found a few answers around that work fine with modifying .Text, .Checked values and so, but none of them worked when I tried changing the .Value property. I can't get that to work on progress bars. Last I tried:

foreach (Control c in this.Controls)
{
    if (c.Name == "test" && c is ProgressBar)
    {
        ((ProgressBar)c).Value = 23;
    }
}

Am I missing a using statement or something?

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Vantalk
  • 367
  • 2
  • 5
  • 21
  • 2
    Code looks right. Are you able to get progressBar? Check by placing breakpoint. – Rohit Vats Jan 05 '14 at 10:44
  • 1
    Also consider to look at [`Control.ControlCollection.Find` method](http://msdn.microsoft.com/en-us/library/system.windows.forms.control.controlcollection.find(v=vs.110).aspx). – Soner Gönül Jan 05 '14 at 10:45
  • I placed an else statement and that is the one that runs.. so the conditions in my if are not satisfied.. I can't understand why – Vantalk Jan 05 '14 at 10:46
  • If you do ((ProgressBar)c).Value, can you see the current value or is that one "null" or zero? – Odrai Jan 05 '14 at 10:46
  • 1
    What is "this"? Maybe you put the ProgressBar in a different control (for e.g. a panel)? – Odrai Jan 05 '14 at 10:47
  • Is really your control named "test" (all lowercase letters)? – Steve Jan 05 '14 at 10:47
  • 3
    I'm pretty sure that you have some nested containers, that means the `progressbar` is not contained directly in your form controls, it may be contained in another container. So using the `Find` method as suggested by `Soner Gonul` is the best choice. – King King Jan 05 '14 at 10:48
  • @Odrai the if statement is not satisfied It doesn't get to run that line. I'll post a picture for everyone to be sure – Vantalk Jan 05 '14 at 10:48
  • @Odrai You were right, moving the bar outside the groupbox makes it work ok. How can I change so that it works inside the groupbox as well? (Groupbox name is: Groupbox2) – Vantalk Jan 05 '14 at 10:51

2 Answers2

1

Assuming that your progressbar control is named "test" (all lowercase letters) and is placed directly on the surface of your form (not inside a groupbox,panel or other control container) then this code should work and simplify your work

foreach (var c in this.Controls.OfType<ProgressBar>().Where(x => x.Name == "test") 
{
   c.Value = 23;
}

instead if the ProgressBar is placed inside a control container (like a panel) the above code should be changed to loop over the controls collection of the container

foreach (var c in this.panel1.Controls.OfType<ProgressBar>().Where(x => x.Name == "test") 
{
   c.Value = 23;
}

As pointed out in the comment by KingKing, if you are absolutely sure that a control named "test" exists in your groupbox then a simple lookup in the controls collection should result in your progressbar. Looping is not necessary in this case

ProgressBar pb = this.groupBox1.Controls["test"] as ProgressBar;
if(pb != null) pb.Value = 23;
Community
  • 1
  • 1
Steve
  • 213,761
  • 22
  • 232
  • 286
  • Odrai was right, I had the bar in a groupbox. Also your examples work perfectly fine. Marked as accepted answer as it was first to be posted on Answers column. – Vantalk Jan 05 '14 at 10:56
  • If you find other answers helpful you could also upvote them. It is a way to show you appreciation for the help given. – Steve Jan 05 '14 at 10:59
  • btw, you don't need any loop through such a *key supported* collection like `ControlCollection`, just passing the control name in the indexer of the `ControlCollection` class and you should get the control if that key exists, otherwise you get `null`, like this `panel1.Controls["test"]` – King King Jan 05 '14 at 10:59
  • I don't exactly understand your last comment as I don't yet know much about ControlCollection. If you can provide an useful edit after what you already posted that would be cool – Vantalk Jan 05 '14 at 11:06
  • 1
    @KingKing is right here. If you are absolutely sure that a control named "test" exists in your groupbox then a simple lookup in the controls collection should result in your progressbar. Looping is not necessary in this case – Steve Jan 05 '14 at 11:10
  • @Steve Read the final edit and tried it. Works perfect! Thank you greatly. Everyone provided a useful answer. TY very much – Vantalk Jan 05 '14 at 11:19
1

The trick here is that Controls is not a List<> or IEnumerable but a ControlCollection.

I recommend using an extension of Control. Add this class to your project:

public static class ControlExtensionMethods
{
    public static IEnumerable<Control> All(this System.Windows.Forms.Control.ControlCollection controls)
    {
        foreach (Control control in controls)
        {
            foreach (Control grandChild in control.Controls.All())
                yield return grandChild;

            yield return control;
        }
    }
}

Then you can do :

foreach(var textbox in this.Controls.All())
{
    // Apply logic to a control
}

Source: Click

Community
  • 1
  • 1
Odrai
  • 2,163
  • 2
  • 31
  • 62
  • I might not need that much versatility. You gave me the first hint on what was wrong, but Steve's answer came first and it's a little easier. Thank you very much. Voting as useful – Vantalk Jan 05 '14 at 11:01