2016-01-29 10 views
6

codice per creare caselle di testo ...ciclo foreach per lo smaltimento controlli iterazioni saltare

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);    
} 

codice per rimuovere tutte le caselle di testo.

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"); } 

} 

quando clicco sul btnAddIncrement ottengo il seguente come previsto ... enter image description here

Ma quando clicco azzerato manca ogni secondo testo. Vedi sotto ...

enter image description here

Non ho idea di quello che sta succedendo qui, ma questo è lo stesso, non importa quanto possa caselle di testo che aggiungo. Manca sempre ogni seconda scatola.

risposta

7

Si consiglia di utilizzare uno standard inversione ciclo for per smaltire i SmartTextBoxes dal suo contenitore

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 non è necessario rimuoverli dal contenitore e ovviamente questo evita due loop (espliciti o impliciti). Anche nella risposta accettata è possibile vedere il motivo per cui il tuo codice salta un controllo ogni due.

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

Il controllo che si vuole eliminare viene rimosso dalla collezione che si effettua l'iterazione. (Non è chiaro il motivo per cui questo non genera l'eccezione standard).

Invece di eseguire il ciclo con un semplice verso al contrario, evitare qualsiasi problema nell'accesso ordinato ai controlli da smaltire.

2

Il codice di rimozione non è corretto poiché si modifica la raccolta Controls chiamando il numero Dispose() ed è per questo motivo che si ottiene il salto dei controlli.

opzione più semplice per rimuovere quelle di un tipo specifico è quello di effettuare le seguenti operazioni:

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

Quando si rimuove un modulo di oggetto this.Controls la raccolta viene modificato e quindi la voce successiva non è quello che ci si aspetta. Yo dovrebbe copiare lo this.Controls in un nuovo elenco. Ad esempio è possibile utilizzare ToArray per creare una copia di this.Controls

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

È necessario rimuovere i controlli da Form.Controls all'inizio e quindi eliminarlo.

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

Provare a selezionare innanzitutto tutti i controlli di SmartTextBox e disporli su un altro ciclo. Pseudocodice:

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

È possibile utilizzare solo il metodo 'OfType ()' di LINQ. – toadflakz

+0

Esattamente. Ma è un po 'difficile scrivere un'espressione LINQ corretta al di fuori dell'IDE. Quindi ho appena scritto lo 'pseudocodice' tenendo presente LINQ. – MobileX