0

I made 10 Labels dynamically.

Now, I'd like to delete them with the same way (dynamically).

What do I have to do ?

Thanks..

for( int i = 1 ; i < 11 ; i++ )
{
    var myLabel = new System.Windows.Forms.Label();
    myLabel.Text = "dynaLabel_" + i.ToString();
    myLabel.Location = new System.Drawing.Point(200, i * 23);       
    Controls.Add(myLabel);
    Application.DoEvents();
    Thread.Sleep(199);
}

enter image description here

Jason
  • 361
  • 3
  • 15
  • Have you **tried** removing them from `Controls`? – AntiTcb May 19 '16 at 12:55
  • @AlexGravely Thanks commet. What do you mean by "Controls"? – Jason May 19 '16 at 12:57
  • You may find it easier if you name your controls such as "dynalabel_"+i.tostring(), as you can then look through by name and not accidentally delete a label you wish to keep – BugFinder May 19 '16 at 13:04
  • A word of advice, don't use `DoEvents()` unless you _fully_ understand the ramifications: http://stackoverflow.com/questions/11352301/how-to-use-doevents-without-being-evil – DonBoitnott May 19 '16 at 13:08
  • @DonBoitnott Nah.. If I "//" the DoEvents, nothing is going to change. Even, there is no Label at all. – Jason May 19 '16 at 13:15
  • Becaus, I guess, my codes goes like this. private void button1_Click ( object sender, EventArgs e ) { Make_it(); } – Jason May 19 '16 at 13:26
  • @Jason do events forces the application to process all outstanding events immediately, most of the time its harmless, however in some instances its can cause major problems `Refresh()` before the sleep should safely do the same – MikeT May 19 '16 at 13:38
  • I'll try it out. Thanks for high level tips. – Jason May 19 '16 at 13:41
  • @Jason note the reason that nothing is happening with out the DoEvents() is that winforms is by default single threaded, this means that your sleep command is suspending the graphics on the form as well as the loop – MikeT May 19 '16 at 13:42
  • Yes, you are hundread times right. I have pain in the neck because of that. Anyways, "Refresh()" works fine with me. Thanks. – Jason May 19 '16 at 13:43
  • a simple way of making it multithreading and not having that problem is to use a backgroundworker see http://www.codeproject.com/Articles/99143/BackgroundWorker-Class-Sample-for-Beginners – MikeT May 19 '16 at 13:45
  • @MikeT Homeworks ? ^^ Thanks, I'll check it out with leisure. – Jason May 19 '16 at 13:48

3 Answers3

2

Just a simple for loop in which you should find out label, remove it from Controls and release allocated resources:

// let's use regular expression to validate name; 
// String.StartsWith is also a good choice
using System.Text.RegularExpressions;
...

// while removing, loop backward
for (int i = Controls.Count - 1; i >= 0; --i) {
  Label label = Controls[i] as Label;

  // Control is Label with specific name
  if ((label != null) && Regex.IsMatch(label.Text, "^dynaLabel_[0-9]+$")) {
    Controls.RemoveAt(i);

    // do not forget to release resources allocated (here is HWND - window handle)
    label.Dispose();
  }
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
1

So is this your homework?

using System.Linq;
...
foreach(Control c in Controls.OfType<Label>().ToList())
{
    //check if correct label if you need to
    Controls.Remove(c);

}
MikeT
  • 5,398
  • 3
  • 27
  • 43
  • LoL.. Kind of.. for late 40's student. – Jason May 19 '16 at 12:59
  • I'll check it out. Thanks. – Jason May 19 '16 at 13:01
  • Brief error: Error CS1061 'Control.ControlCollection' does not contain a definition for 'ToList' and no extension method 'ToList' accepting a first argument of type 'Control.ControlCollection' could be found (are you missing a using directive or an assembly reference?) – Jason May 19 '16 at 13:06
  • do you have a `using System.Linq;` at the top of the page? – MikeT May 19 '16 at 13:07
  • Hmm. Just added "using System.Linq;" – Jason May 19 '16 at 13:09
  • Unfortunately, this leads to *resource leakage*: you should `Dispose` removed labels – Dmitry Bychenko May 19 '16 at 13:10
  • System.Linq exands all enumerable lists with many useful functions, its usually included by default – MikeT May 19 '16 at 13:11
  • I added "Linq", but still have the same error message. – Jason May 19 '16 at 13:12
  • @MikeT: `Controls.OfType()` and only then `.ToList()`, the loop should be `foreach(Control c in Controls.OfType().ToList())` – Dmitry Bychenko May 19 '16 at 13:15
  • @DmitryBychenko thank you, been a while since i worked in winforms i'd forgotted controls collection only implements IEnumerable not IEnumerable – MikeT May 19 '16 at 13:17
  • I have to clikc 4 times. Once, odd numbered Labels gone.(I have 2, 4, 6, 8 and 10) Twice, half gone (I still have 4, 8) Third, # 8 gone. Last, OK, have nothing. Looks not good. – Jason May 19 '16 at 13:19
  • please note that in order to keep this simple i've missed out the final clean up operation, as a label contains links to the operating system then it wont always be deleted automatically because the operating system may still have a link to it, adding `c.Dispose()` removes the OS links – MikeT May 19 '16 at 13:26
1

You could use Controls and LINQ Where to do the job:

var labels = Controls.Cast<Control>()
    .Where(c => c is Label && c.Text.StartsWith("dynaLabel_"));
foreach (var label in labels){
    Controls.Remove(label);
    label.Dispose();
}

Since you create the labels as Label and having the Text starting with value of dynaLabel_, your LINQ should also find those specific labels. Thus, you use both c is Label and StartsWith("dynaLabel_") there.

Ian
  • 30,182
  • 19
  • 69
  • 107