2

I have the following code:

private void addPath(Label labelRound)
    {
        var path = new System.Drawing.Drawing2D.GraphicsPath();
        path.AddEllipse(0, 0, labelRound.Width, labelRound.Height);
        labelRound.Region = new Region(path);
    }

I have several Labels named lbl0_1, lbl0_2, etc. Currently I do this:

addPath(lblLight0_1);
addPath(lblLight0_2);
addPath(lblLight0_3);

This seems not right, how is the "correct" way to go through all the labels?

Any hint appreciated!

PrimuS
  • 2,505
  • 6
  • 33
  • 66
  • Well you could create a list/array of the labels and then loop over that. – Johan Aug 26 '15 at 09:08
  • you can see - [loop through all controls](http://stackoverflow.com/questions/15186828/loop-through-all-controls-on-a-form-even-those-in-groupboxes) here all controls are found, if there are no containers and you dont want to do it recursively for each container then [this will be helpful](http://stackoverflow.com/questions/1788490/how-can-i-iterate-through-all-checkboxes-on-a-form). – Kryptonian Aug 26 '15 at 09:19

4 Answers4

4

That's correct, this is not the Right Way™. Effective Winforms programming strongly relies on inheritance to let the usual benefits of object-oriented programming pay off. Add a class to your project and paste this code:

using System;
using System.Windows.Forms;

public class OvalLabel : Label {
    protected override void OnResize(EventArgs e) {
        using (var path = new System.Drawing.Drawing2D.GraphicsPath()) {
            path.AddEllipse(0, 0, this.Width, this.Height);
            this.Region = new System.Drawing.Region(path);
        }
        base.OnResize(e);
    }
}

Compile and you get the new control on the top of the toolbox. Use it in your designs, replacing existing Label controls where appropriate. Quickest way to do that is with Search+Replace. You probably want a constructor to set the default for some properties. And note that no code is required in the rest of your app at all.

Note the other benefits, it still works correctly when you resize the labels and you get the WYSIWYG view in the designer. And you'll now also have a decent shot at fixing the other problems you have to address, like the Text getting clipped by the oval. Or not use the Region property at all but draw a much better looking anti-aliased oval in an override for OnPaintBackground(). Etcetera.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
3

You can iterate through all controls with a foreach, check if they're a label and then add them:

foreach (Control control in Controls) 
{
    if (control is Label) 
    {
        addPath(control);
    } 
}

Depending on how many controls you have this might be inefficient to do every time. Maybe at startup you could use the same loop to create a List<T> of labels and then iterate the list instead.

Equalsk
  • 7,954
  • 2
  • 41
  • 67
2
Label[] labels = new Label[] { lblLight0_1, lblLight0_2, lblLight0_3 };

foreach(Label label in labels)
{
    addPath(label);
}

At least this is how you "loop through" your labels. Sure thing, you have to manage the labels array and add/remove labels as you need it. If you add them programmatically at some other point in your code, then I'd recommend to use a List<Label> instead of an array, but that's up to you.

There is no "correct way" to update all labels. It all depends on your design and what you do with these labels. The way you do it can be perfectly legit.

KeyNone
  • 8,745
  • 4
  • 34
  • 51
0
Controls.OfType<Label>().Where(p => 
    p.Name.StartsWith("lblLight0_")).ToList().ForEach(addPath);
Reza ArabQaeni
  • 4,848
  • 27
  • 46