Usunięcie wszystkich kontrolek TextBox z formy. (usuwa co 2)

0

Witam.
Uczę się programować w C# w Visual Studio 2010.

Potrzebuję usunąć wszystkie kontrolki typu TextBox z formy. Używam do tego pętli foreach do wyszukania kontrolek i metody Dispose() do usunięcia. Problem jest tego typu, że usuwa mi co 2 kontrolkę? Gdzie mam błąd?

Oto kod:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication3
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Control.ControlCollection coll = this.Controls;
            foreach (Control c in coll)
            {
                if (c.GetType().ToString() == "System.Windows.Forms.TextBox")
                {
                MessageBox.Show("OK:" + c.GetType(), "Index: " + c.Name, MessageBoxButtons.OK, MessageBoxIcon.Information);
                c.Dispose();





                 }
            }
        }
    }
}

 
2

(c.GetType().ToString() == "System.Windows.Forms.TextBox") - niebezpiecznie zbliżasz się w stronę perełek/The Daily WTF.
Radziłbym jednak (c.GetType() == typeof(TextBox)).

Co do błędu - prawdopodobnie masz klasyczny błąd związany z pętlami. Podejrzewam że c.Dispose() usuwa kontrolkę z listy kontrolek (w pętli foreach nie może nastąpić modyfikacja kolekcji, ten kod nie powinien działać!). Jeśli to prawda, zastanów się nad działaniem poniższego kodu (pisane z palca ale powinno działać):

List<int> ints = new List<int>();
ints.Add(1);
ints.Add(2);
ints.Add(3);
ints.Add(4);
ints.Add(5);
ints.Add(6);
for(int i = 0; i < ints.Count; i++)
{
    Console.WriteLine(i.ToString());
}
0

dobrze byłoby też kontrolki przeszukiwać rekurencyjnie, np. za pomocą funkcji:

 
public static IEnumerable<System.Web.UI.Control> AllChildControls(this System.Web.UI.Control instance)
{
  foreach (System.Web.UI.Control control in instance.Controls)
  {
    yield return control;
    foreach (System.Web.UI.Control childControl in control.AllChildControls())
      yield return childControl;
  }
}
1

Nie jestem pewien czy samo Dispose() wystarczy. Sugeruję raczej użyć Controls.Remove(c), ewentualnie później Dispose().

0

Dzięki śliczne. C# robię od 2 dni i jest to mój pierwszy język więc myślę, że perełki zdarzały się każdemu początkującemu :D
Co do problemu to zastosowanie pętli for pomogło :)
Poniższy kod spełnia założone zadanie:

private void button1_Click(object sender, EventArgs e)
{
    Control.ControlCollection kolekcja = this.Controls;
    for (int i = kolekcja.Count - 1; i >= 0; i--)
    {
        if (kolekcja[i] is TextBox)
        {
            kolekcja.Remove(kolekcja[i]);
        }
    }
}

JESZCZE RAZ WIELKIE DZIĘKI!

0
MSM napisał(a)

(c.GetType().ToString() == "System.Windows.Forms.TextBox") - niebezpiecznie zbliżasz się w stronę perełek/The Daily WTF.
Radziłbym jednak (c.GetType() == typeof(TextBox)).

Nie można po prostu
if(c is TextBox) ? xd. to też perełka z Twojej strony.

1 użytkowników online, w tym zalogowanych: 0, gości: 1