2016-01-29 14 views
6

kod do tworzenia otaczaniem ...Foreach Pętla do usuwania sterujące Pomijanie iteracji

private void btnAddIncrement_Click(object sender, EventArgs e) 
{    
    SmartTextBox dynamictextbox = new SmartTextBox(); 

     dynamictextbox.BackColor = Color.Bisque; 
     dynamictextbox.Width = this.tbWidth; 
     dynamictextbox.Left = (sender as Button).Right + this.lastLeft; 
    dynamictextbox.K = "Test"; 

    this.lastLeft = this.lastLeft + this.tbWidth; 
    dynamictextbox.Top = btnAddStart.Top; 
    this.Controls.Add(dynamictextbox);    
} 

Kod usunąć wszystkie pola tekstowe.

foreach (Control c in this.Controls) 
{ 

    if (c.GetType() == typeof(BnBCalculator.SmartTextBox)) 
    { 
     count++; 
     //MessageBox.Show((c as SmartTextBox).K.ToString()); 
     c.Dispose(); 
    } 
    // else { MessageBox.Show("not txtbox"); } 

} 

Kiedy klikam btnAddIncrement otrzymuję następujący zgodnie z oczekiwaniami ... enter image description here

Ale gdy klikam zresetować to strzela co drugie pole tekstowe. Zobacz poniżej ...

enter image description here

pojęcia, co tu się dzieje, ale to jest taka sama bez względu na to w jaki sposób można dodać tekst pola ja. Zawsze brakuje co drugiego pudełka.

Odpowiedz

7

Należy użyć odwrotnego standard pętli do dysponowania przez SmartTextBoxes z pojemnika

for(int x = this.Controls.Count - 1; x >= 0; x--) 
{ 
    BnBCalculator.SmartTextBox c = this.Controls[x] as BnBCalculator.SmartTextBox; 
    if (c != null) 
    { 
     count++; 
     c.Dispose(); 
    } 
} 

According to this question/answer nie trzeba, aby je usunąć z kontenera i oczywiście unika się dwóch pętli (jawnych lub niejawnych). Również w zaakceptowanej odpowiedzi zobaczysz przyczynę, dla której twój kod przeskakuje kontrolę co dwa.

if (parent != null) 
{ 
    parent.Controls.Remove(this); 
} 

Kontrolka, którą chcesz wyrzucić, została usunięta z kolekcji, którą przerabiasz. (Nie jest jasne, dlaczego nie spowoduje to wyjątku standardowego).

Zamiast pętli z prostym do tyłu uniknąć problemu w zamówionym dostępie do kontroli do dysponowania.

2

Twój kod usuwania jest niepoprawny, ponieważ modyfikujesz kolekcję Controls, dzwoniąc pod numer Dispose(), dzięki czemu pomijasz elementy sterujące.

Najprostszym rozwiązaniem, aby usunąć te określonego typu jest wykonanie następujących czynności:

var smartTbs = this.Controls.OfType<BnBCalculator.SmartTextBox>().ToList(); 
smartTbs.ForEach(x => x.Dispose()); 
2

Po usunięciu formularz elementu this.Controls zbiór jest modyfikowany i tak kolejna pozycja nie jest to, czego można się spodziewać. Yo powinien skopiować this.Controls do nowej listy. Na przykład można użyć ToArray zrobić kopię this.Controls

foreach (Control c in this.Controls.ToArray()) 
{ 
    ... 
} 
1

Najpierw należy usunąć formanty z Form.Controls, a następnie wyrzucić je.

var controlsToRemove = new List<Control>(); 
foreach (Control c in this.Controls) 
{ 
    if (c is BnBCalculator.SmartTextBox) 
     controlsToRemove.Add(c); 
} 

foreach (Control c in controlsToRemove) 
{ 
    Controls.Remove(c); 
} 
0

Spróbuj najpierw wybrać wszystkie elementy sterujące SmartTextBox i wyrzucić je w innej pętli. Pseudokod:

SmartTextBoxes = Select From this.Controls Where (c.GetType() == typeof(BnBCalculator.SmartTextBox)); 
    foreach(stb in SmartTextBoxes) { stb.Dispose(); } 
+1

Można po prostu użyć metody LINQ 'OfType ()'. – toadflakz

+0

Dokładnie. Ale nieco trudniej jest napisać poprawne wyrażenie LINQ poza IDE. Więc właśnie napisałem "pseudokod", mając na uwadze LINQ. – MobileX

Powiązane problemy