dynamiczne generowanie Form2

0

Witam

Mam pytanie natury "czy da się?".

W Form1 obrabiam jakąś porcję danych i w efekcie otrzymuję tablicę jednowymiarową typu ArrayList[] n-elementową:

ArrayList[] tablicaZForm1 = new ArrayList[n];

gdzie n może przyjmowac wartosci z zakresu 1-5. poszczególne kolekcje ArrayList w tej tablicy mają losową liczbe elementów z zakresu 1-1000.
Chciałbym zaprezentowac zawartosc tej tablicy w Form2, w którym dynamicznie tworzona byłaby kontrolka TabControl z ilością zakładek równą wymiarowi n tablicy z Form1. ponadto w każdej zakładce miałaby być tworzona kontrolka ListBox do których kolejno pakowana miałaby być zawartość poszczególnych ArrayList z tablicy z From1. Czy jest możliwe takie generowanie "w biegu" Form2?

Maksymalny wyglad takiego Form2 wygladałby tak:
user image

Jeżeli tak to prosiłbym o hasła klucze, wokół czego/jakich zagadnień mam drążyć, na razie zgłębiam przekazywanie danych z jednego okna do drugiego - czy w moim przypadku trzeba byłoby to robić przez konstruktor Form2?

2

Dlaczego używasz ArrayList? W 90% przypadków nie ma to sensu, w 10% oznacza błąd projektowy, dopiero reszta ma uzasadnienie. Zawsze lepiej użyć List<T>.

Generowanie całego GUI w biegu jest jak najbardziej możliwe. Zresztą... przecież GUI zawsze generowane jest w biegu, podczas uruchamiania programu. ;) Zajrzyj do pliku Form1.designer.cs - nic tam nie pisz, tylko go poczytaj - tak właśnie wygląda definiowanie wyglądu formularza, tworzenie nowych kontrolek, dodawanie ich do Form, ustawianie ich struktury.

Ja to widzę tak:

  1. W Form1 tworzysz obiekt Form2 i przekazujesz mu (np. w konstruktorze) te wszystkie dane, które chcesz wyświetlić, czyli List<List<T>>
  2. W konstruktorze Form2 odbierasz te dane, idziesz w pętli i przekazujesz każdą List<T> do metody o nazwie np. AddTab.
  3. Metoda ta dodaje do tabControl nowy TabPage, umieszcza w nim ListBoxa, a następnie wpisuje do niego n danych z listy.
0

Dzięki za podpowiedzi właśnie tak zacząłem to robić.

Jeszcze jedno pytanie: otwieram Form2 ze zdarzenia tak:

 
                ArrayList[] tablicaLinii = new ArrayList[lewyPlik.IloscWatkow];
                tablicaLinii = lewyPlik.PobranieTresciProgramu(listBox_lewy.SelectedItem.ToString());
                PodgladProgramu oknoLewe = new PodgladProgramu(tablicaLinii);                   //Form2
                oknoLewe.Show();

i spodziewałem się że niestety po wywołaniu kolejne razy tego samego zdarzenia będzie mi jakby w tym samym oknie "odświeżało" zawartość a tu mi otwiera tych Form2 tyle ile razy wywołam to zdarzenie. Z tego wniosek że jak już utworzę jakiśobiekt to on zyje swoim zyciem. Akurat to mi pasuje ale dlaczego tak się dzieje? Przecież za każdym razem tworzę obiekt o narzuconej nazwie oknoLewe nie dodaje go do żadnej kolekcji, nazwy są stałę a jednak otwiera w nowych oknach?

PS. Co do tego dlaczego używam ArrayList a nie List<T>, to odpowiedź jest banalna - na razie jeszcze nie wiem co to jest List<T> ;).
Ale kończe już jedną książkę (w której nic nie było o List<T>) i będe gotowy do podejścia do ksiązki A.Boducha (tam coś jest o tym). Wcześniej podchodziłem do jego ksiązki dwa razy jako do pierwszej ksiązki na temat C# ale mózg mi wysiadał za każdym razem przy tablicach, zbyt dynamiczna akcja i zbyt szybko wprowadza nowych bohaterów w niej jak na pierwszy kontakt z programowaniem. Ale po podkładzie w postaci Klausa Michelsena myślę że już jestem gotów na Boducha ;)

0

Co do tego dlaczego używam ArrayList a nie List<T>, to odpowiedź jest banalna - na razie jeszcze nie wiem co to jest List<T>

Jest to tyle co ArrayList, ale o elementach podanego typu (to jest to „T”):

List<int> lista = new List<int>(); // lista elementów typu int, konkretnie i wyłącznie
lista.Add(5);
List<string> listaStringow;
List<MojaKlasa> listaMoja;

ArrayList przechowuje wszystkie elementy rzutowane na object, czyli podobnie jak List<object>.

0
Varran napisał(a)

Akurat to mi pasuje ale dlaczego tak się dzieje? Przecież za każdym razem tworzę obiekt o narzuconej nazwie oknoLewe nie dodaje go do żadnej kolekcji, nazwy są stałę a jednak otwiera w nowych oknach?

No właśnie - za każdym razem tworzysz nowy obiekt, nigdy go nie niszczysz i nigdy niczym nie zastępujesz. On nie ma prawa magicznie zniknąć sam z siebie.

0
Azarien napisał(a)

ArrayList przechowuje wszystkie elementy rzutowane na object, czyli podobnie jak List<object>.

jeżeli rzutowanie i to w dwie strony to w mom przypadku pierwszy raz ze string do object a pozniej z object na string to w ktoryms przypadku (chyba rzutujac ze string->object) mam zagrozenie utraty czesci danych, tak?

0
Varran napisał(a)

jeżeli rzutowanie i to w dwie strony to w mom przypadku pierwszy raz ze string do object a pozniej z object na string to w ktoryms przypadku (chyba rzutujac ze string->object) mam zagrozenie utraty czesci danych, tak?

Po pierwsze musisz napisać więcej kodu, żeby zamienić object z powrotem na interesujący Cię konkretny obiekt.
Po drugie taka zamiana w tę i z powrotem zajmuje niepotrzebnie zasoby.
Po trzecie, gdy już masz pojemnik typu śmietnik (ArrayList), możesz oprócz np. stringów, które chcesz tam trzymać wsadzić przypadkiem obiekt zupełnie innej klasy, co może spowodować błędy albo jakieś dziwne zachowania w programie. Ty się nie zorientujesz w pierwszej chwili, bo kompilator Ci tego nie podpowie. W przypadku List<T> to on pilnuje czy nigdzie nie popełniasz błędu. Lepiej sobie ułatwiać niż utrudniać. :)

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