Laden...

foreach - Problem

Erstellt von Buck vor 17 Jahren Letzter Beitrag vor 17 Jahren 2.619 Views
B
Buck Themenstarter:in
26 Beiträge seit 2006
vor 17 Jahren
foreach - Problem

Hi,
mir ist der allgmeine Syntax für eine foreach-Schleife bekannt und ich habe natürlich auch schon foreach-Schleifen benutzt. Aber nun stehe ich vor einem Problem! Ich habe keine Ahnung ob mein Vorhaben überhaupt möglich ist, weil nirgends etwas ähnliches finden konnte.

je nach der Anzahl der Einträge in der Datenbank generiere ich Labels auf dem Form.

myTerminLabel = new Label();
...
myTerminLabel.TextAlign = ...
this.panelTermine.Controls.Add(myTerminLabel);

ich möchte mittels einer foreach-Schleife nun alle myTerminLabel-Felder löschen!

panelTermine.Controls.Remove(myTerminLabel);

ist das möglich, oder müssen die Labels anders erzeugt werden?

mfg
Buck

T
94 Beiträge seit 2006
vor 17 Jahren

foreach (Control ctrl in Controls)
{
 if (ctrl is Label) // die if kannst du ja gegebenfalls verändern
 {
  // label entfernen
 }
}

das sollte das sein, was du suchst (hoff ich ;>)

mfg

If you don't like me for who I am, then you don't like me for who I am, but all you're gonna get, is who I am.

564 Beiträge seit 2005
vor 17 Jahren

Dafür musst du eine for-Schleife benutzen.
Oder noch besser:


while(panelTermine.Controls.Count > 0)
{
    panelTermine.Controls.Remove(panelTermine.Controls[0]);    
}

B
Buck Themenstarter:in
26 Beiträge seit 2006
vor 17 Jahren

ich danke euch für die schnelle unterstützung! es funktioniert soweit!

mfg
Buck

F
722 Beiträge seit 2005
vor 17 Jahren

Original von thejudge

  
foreach (Control ctrl in Controls)  
{  
 if (ctrl is Label) // die if kannst du ja gegebenfalls verändern  
 {  
  // label entfernen  
 }  
}  
  

Hallo thejudge,

das wird nicht funktionieren, da ctrl nicht aus der zu durchlaufenden collection gelöscht werden darf.

B
1.529 Beiträge seit 2006
vor 17 Jahren

using( List<Control> ctrl2del = new List<Control>( this.Controls.Count ) )
{
   foreach( Control ctrl in this.Controls )
   {
      if (ctrl is Label)
      {
         ctrl2del.Add( ctrl );
      }
   }
   foreach( Control ctrl in ctrl2del )
   {
      this.Controls.Remove( ctrl );
      ctrl.Dispose();
   }
}
4.506 Beiträge seit 2004
vor 17 Jahren

Hallo Borg,

das kann nun unmöglich Dein Ernst sein, oder hast Du jetzt das Beispiel nur so hingebogen, dass zwingend foreach benutzt wird?

Also zunächst eine temporäre Liste zu löschen, um dann die Originalliste von den temporären Listenelmenten zu löschen ist sehr umständlich und unperformant.

Also For und While sind hier die Mittel zur Wahl. Falls es nur auf Foreach abgestimmt ist, gut, aber der Rat eine For/While Schleife zu benutzen halte ich hier für sehr wichtig.

Gruß
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

B
Buck Themenstarter:in
26 Beiträge seit 2006
vor 17 Jahren

Hallo Leute!

Ich habe vergessen, dass neben den Labelfelder auch noch TextBox-Elemente im Panel sind.
Mit der While-Schleife lösche ich natürlich alles, was ich ja eigentlich nicht will. ich habe versucht, dies mit einer if-schleife zu unterbinden, aber es funkt nicht!


while(panelTermine.Controls.Count > 0)
{
panelTermine.Controls.Remove(panelTermine.Controls[0]);
}

mfg
Buck

6.862 Beiträge seit 2003
vor 17 Jahren

Kein Wunder, es gibt auch keine If-Schleifen 😉

Prinzipiell ist die Abfrage nach dem Typ aber richtig. Einfach mit is prüfen obs das Control ein Label ist, und nur dann halt deine Aktionen ausführen.

Baka wa shinanakya naoranai.

Mein XING Profil.

B
Buck Themenstarter:in
26 Beiträge seit 2006
vor 17 Jahren

ok, ich gestehe meinen fehler ein - if ist keine Schleife 😁

was mein problem betrifft, ich lege es erstmal weg. ich glaube in diesem fall scheitere ich am grundlegenden!

mfg
Buck

B
1.529 Beiträge seit 2006
vor 17 Jahren

das kann nun unmöglich Dein Ernst sein

Es war doch ein foreach-Problem 😉

this.SuspendLayout();
for ( int i = 0; i < this.Controls.Count; )
{
   if (this.Controls[i] is Label)
   {
      Control ctrl = this.Controls[i];
      this.Controls.RemoveAt( i );
      ctrl.Dispose();
   }
   else
   {
      i++;
   }
}
this.ResumeLayout(true);

Besser?

T
512 Beiträge seit 2006
vor 17 Jahren

Wenn gelöscht werden soll, geh ich immer von hinten ran, dann wirds auch ne schöne Schleife:

for ( int i = this.Controls.Count - 1; i >= 0; --i )
{
   if (this.Controls[i] is Label)
   {
      Control ctrl = this.Controls[i];
      this.Controls.RemoveAt( i );
      ctrl.Dispose();
   }
}

Finds irgendwie unschön nur halbe for-Schleifen hinzuschreiben.

e.f.q.

Aus Falschem folgt Beliebiges

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Traumzauberbaum,

außerdem ist von hinten Löschen gerade beim Löschen von vielen Einträgen in großen Listen deutlich performanter.

Allerdings ist das wiederholte Löschen mit Remove immer noch eine O(n^2)-Operation. Wenn man wirklich schnell (im Sinne von O(n)) löschen will, dann fügt man die nicht zu löschenden Objekte am Ende einer neuen Liste hinzu (und muss dann im Zweifel noch die Originalliste komplett löschen und die neue Liste zurück in die Originalliste kopieren (aber auch damit bleibt es bei O(n))).

herbivore

B
Buck Themenstarter:in
26 Beiträge seit 2006
vor 17 Jahren

So, jetzt habe ich eine lösung vorliegen, die eigentlich - so glaube ich zumindest - funktionieren sollte. ABER es funkt nicht zu 100% und ich weiß nicht was jetzt falsch ist.

Nochmals zu meinem Problem: In einem Panel sind Label-Felder und Buttons. Bei einer Methode Löschen sollen ALLE Labels auf einmal gelöscht werden - Nur die Buttons sollen bleiben!!!

 foreach (Control ctrl in panelTermine.Controls)
{
if (ctrl is Label)
{
panelTermine.Controls.Remove(ctrl);
}
}
 

Ach ja, das Problem wird ersichtlich, wenn man sich 'ctrl' anzeigen lässt.

mfg
Buck

F
722 Beiträge seit 2005
vor 17 Jahren

Hallo Buck,

hast du dir eigentlich den Thread durchgelesen? =) Es wurden doch jetzt genug Lösungswege beschrieben. Und auch welche, die sich nicht für dein Vorhaben eignen, z.b. Löschen mittels einer foreach Iterration.

Zum Löschen aller Labels:


for (int i=this.Controls.Count-1; i>=0; i--)            
            {
                if (this.Controls[i] is Label)
                {
                    this.Controls.RemoveAt(i); 
                }
            }

B
Buck Themenstarter:in
26 Beiträge seit 2006
vor 17 Jahren

@ feadur! Ob du es glaubst oder nicht, ich habe mir den thread durchgelesen und die einzelnen antworten ausprobiert! =) Schließlich hat dein beitrag zu einem perfekten ergebnis geführt! Danke!!!

mfg
Buck

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Buck,

allso wenn du so einfache Probleme nicht duch die Antworten hier im Thread, sondern nur dadurch, dass jemand dir (freunlicherweise) den fertigen Code vortippt, dann solltest du echt überlegen, ob du Hobby oder Beruf verfehlt oder zumindest die falsche Einstelllung dazu hast. Solche Probleme muss man sogar komplett ohne fremde Hilfe lösen können (lernen).

herbivore

B
Buck Themenstarter:in
26 Beiträge seit 2006
vor 17 Jahren

Hi herbivore!

was heißt hier den "feritigen code"? wenn du möchtest werde ich meinen code posten, damit du die unterschiede siehst!!!
ich frage mich nur, was du mir eigentlich sagen möchtest. soll ich mich entschuldigen, weil es bei mir nicht funktionierte? gott sei dank gibt es mitglieder, die konstruktive hilfe anbieten! nur so kann man lernen und nicht durch erniedrigende posts.

mfg
Buck

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Buck,

es war nicht als Erniedrigung, sondern als guter Rat gemeint.

Es war genau so gemeint, wie ich es gesagt habe. Also sachlich.

herbivore