Indexové seznamy známe už pole, kde ale musí být předem známa velikost indexové seznamy umí růst dynamicky
Viz nedávný příklad s převodem souboru na velká písmena. Řešení pomocí pole: private void tlačítkoprocházetvýchozí_click(object sender, EventArgs e) if (oknootevřenísouboru.showdialog() == DialogResult.OK) polevýchozí.text = oknootevřenísouboru.filename; private void tlačítkoprocházetvýsledný_click(object sender, EventArgs e) if (oknouloženísouboru.showdialog() == DialogResult.OK) polevýsledný.text = oknouloženísouboru.filename; private void tlačítkoproveď_click(object sender, EventArgs e) // Zjisti počet řádků výchozího souboru StreamReader výchozí = new StreamReader(poleVýchozí.Text, Encoding.Default); int početřádků = 0; while (výchozí.readline()!= null) početřádků++; výchozí.close(); // Připrav pole pro uložení všech řádků souboru... string[] řádky = new string[početřádků]; //... a jednotlivé řádky do něj načti výchozí = new StreamReader(poleVýchozí.Text, Encoding.Default); for (int číslořádku = 0; číslořádku < početřádků; číslořádku++) řádky[číslořádku] = výchozí.readline(); výchozí.close(); // Obsah pole vypiš do výsledného souboru // v opačném pořadí, tzn. počínaje posledním řádkem StreamWriter výsledný = new StreamWriter(poleVýsledný.Text, false, Encoding.Default); for (int číslořádku = početřádků - 1; číslořádku >= 0; číslořádku--) výsledný.writeline(řádky[číslořádku]); výsledný.close(); MessageBox.Show("HOTOVO!");
Indexový seznam instance třídy List<T>, kde T je skutečný typ třída List patří do jmenného prostoru System.Collections.Generic > potřeba using prvky se přidávají metodou Add po vytvoření je seznam prázdný aktuální počet prvků vrací metoda Count (u polí to bylo Length)
using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Windows.Forms; namespace V_opačném_pořadí public partial class oknoprogramu : Form public oknoprogramu() InitializeComponent(); private void tlačítkoprocházetvýchozí_click(object sender, EventArgs e) if (oknootevřenísouboru.showdialog() == DialogResult.OK) polevýchozí.text = oknootevřenísouboru.filename; private void tlačítkoprocházetvýsledný_click(object sender, EventArgs e) if (oknouloženísouboru.showdialog() == DialogResult.OK) polevýsledný.text = oknouloženísouboru.filename; private void tlačítkoproveď_click(object sender, EventArgs e) // Vytvoř prázdný seznam List<string> řádky = new List<string>(); // Načítej řádky a postupně plň seznam StreamReader výchozí = new StreamReader(poleVýchozí.Text, Encoding.Default); string řádek; while ((řádek = výchozí.readline())!= null) řádky.add(řádek); výchozí.close(); // Obsah seznamu vypiš do výsledného souboru // v opačném pořadí, tzn. počínaje posledním řádkem StreamWriter výsledný = new StreamWriter(poleVýsledný.Text, false, Encoding.Default); for (int číslořádku = řádky.count - 1; číslořádku >= 0; číslořádku--) výsledný.writeline(řádky[číslořádku]); výsledný.close(); MessageBox.Show("HOTOVO!");
Př. záznam pozic kliknutí myší, pozn. Point známe z příkladu se srdíčkem using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; namespace Myšince public partial class oknoprogramu : Form List<Point> seznammyšinců = new List<Point>(); int šířkamyšince = 5, výškamyšince = 2; Color barvamyšince = Color.Black; public oknoprogramu() InitializeComponent(); private void oknoprogramu_mousedown(object sender, MouseEventArgs e) Point bod = new Point(e.X, e.y); seznammyšinců.add(bod); Refresh(); private void oknoprogramu_paint(object sender, PaintEventArgs e) Graphics kp = e.graphics; Brush štětec = new SolidBrush(barvaMyšince); foreach (var myšinec in seznammyšinců) // LH = Levý Horní (roh obdélníka) int xlh = myšinec.x - šířkamyšince / 2; int ylh = myšinec.y - výškamyšince / 2; kp.fillrectangle(štětec, xlh, ylh, šířkamyšince, výškamyšince);
Operace nad seznamem naplnění daty dotaz na konkrétní prvek přidání prvku na konec seznamu vložení prvku doprostřed seznamu odstranění prvku změna pořadí prvků
použijeme komponentu listbox
Načtení dat private void tlačítkoprocházet_click(object sender, EventArgs e) if (oknootevřenísouboru.showdialog() == DialogResult.OK) polejménosouboru.text = oknootevřenísouboru.filename; private void tlačítkonačtiseznam_click(object sender, EventArgs e) // Vymaže stávající položky seznamu listbox.items.clear(); // Načte seznam ze souboru do listboxu try StreamReader soubor = new StreamReader(poleJménoSouboru.Text, Encoding.Default); string řádek; while ((řádek = soubor.readline())!= null) listbox.items.add(řádek); soubor.close(); catch MessageBox.Show("Chyba při načítání seznamu", "CHYBA");
Zobrazení vybraného prvku private void tlačítkovypišvybrané_click(object sender, EventArgs e) int index = listbox.selectedindex; MessageBox.Show(listBox.Items[index].ToString()); Smazání vybraného prvku private void tlačítkosmažvybrané_click(object sender, EventArgs e) int index = listbox.selectedindex; listbox.items.removeat(index);
Vložení nového prvku private void tlačítkovložnové_click(object sender, EventArgs e) int index = listbox.selectedindex; string vkládanéjméno = polevkládanéjméno.text; if (index >= 0) listbox.items.insert(index, vkládanéjméno); else listbox.items.add(vkládanéjméno); polevkládanéjméno.text = null;
Posun prvku nahoru private void tlačítkoposuňnahoru_click(object sender, EventArgs e) int index = listbox.selectedindex; // Prohodí sousední prvky var schovej = listbox.items[index]; listbox.items[index] = listbox.items[index - 1]; listbox.items[index - 1] = schovej; // Posune výběr spolu s prvkem listbox.selectedindex--;
Posun prvku dolů private void tlačítkoposuňdolů_click(object sender, EventArgs e) int index = listbox.selectedindex; // Prohodí sousední prvky var schovej = listbox.items[index]; listbox.items[index] = listbox.items[index + 1]; listbox.items[index + 1] = schovej; // Posune výběr spolu s prvkem listbox.selectedindex++;
Zbytek programu private void polejménosouboru_textchanged(object sender, EventArgs e) tlačítkonačtiseznam.enabled = polejménosouboru.text.length > 0; private void polevkládanéjméno_textchanged(object sender, EventArgs e) tlačítkovložnové.enabled = polevkládanéjméno.text.length > 0; private void listbox_selectedindexchanged(object sender, EventArgs e) int index = listbox.selectedindex; bool něcovybráno = index >= 0; tlačítkovypišvybrané.enabled = něcovybráno; tlačítkosmažvybrané.enabled = něcovybráno; // prvek na indexu 0 (nejhořejší) nahoru posouvat nelze tlačítkoposuňnahoru.enabled = index > 0; // nejspodnější prvek dolů posouvat nelze int indexposledního = listbox.items.count - 1; tlačítkoposuňdolů.enabled = něcovybráno && index < indexposledního;
Kopírování seznamu private void tlačítkokopíruj_click(object sender, EventArgs e) List<string> seznamhlavní, seznamzáložní; seznamhlavní = new List<string>() "Jana", "Petr", "Kateřina" ; if (knoflíksprávně.checked) seznamzáložní = new List<string>(seznamHlavní); else seznamzáložní = seznamhlavní; seznamhlavní[0] = "Milan"; MessageBox.Show("Prvním prvkem záložního seznamu je " + seznamzáložní[0]);
Zálohu seznamu nejde provést jako např. zálohu čísla, tj. např. int záloha = číslo; Pokud se o to pokusíme, dojde pouze ke zkopírování odkazu do paměti na původní seznam, takže nový pracuje s obsahem původního. List<T> seznamzáložní = seznamhlavní; Pokud chceme opravdu nový seznam, musíme použít konstruktor, který původní zkopíruje na nové místo. List<T> seznamzáložní = new List<T>(seznamHlavní);
Upravte předchozí program tak, aby nabízel ještě třetí možnost zkopírovat seznam ručně po položkách. private void tlačítkokopíruj_click(object sender, EventArgs e) List<string> seznamhlavní, seznamzáložní; seznamhlavní = new List<string>() "Jana", "Petr", "Kateřina" ; if (knoflíksprávněkonstruktorem.checked) seznamzáložní = new List<string>(seznamHlavní); else if (knoflíknesprávně.checked) seznamzáložní = seznamhlavní; else // přidaná varianta po složkách seznamzáložní = new List<string>(); foreach (var složka in seznamhlavní) seznamzáložní.add(složka); seznamhlavní[0] = "Milan"; MessageBox.Show("Prvním prvkem záložního seznamu je " + seznamzáložní[0]);
Napište program, který při zadání hesla napíše, jestli už nebylo v minulosti (od spuštění programu) někdy použito. Prohledávání seznamu hesel udělejte buď ručně, nebo použijte metodu IndexOf seznamu.
Udělejte program, který bude losovat 6 čísel ze 49 (Sportka). Žádné číslo se nesmí opakovat. Udělejte program, který načte textový soubor a zjistí, jestli v něm neexistují dva stejné řádky.
Vyrobte program, který ze seznamu závodníků vyrobí startovní listinu. 8:00 Kudrna Radoslav 8:10 Hůdek Jaroslav 8:20 Groch Milan 8:30 Navrátil Milan 8:40 Petružálek Radek 8:50 Chýna Jan 9:00 Kazda Martin 9:10 Švácha Jaroslav 9:20 Polák Jiří 9:30 Kubále Zdeněk 9:40 Jerie Bohumil. http://www.gfp.cz/prg/seznam_prihlasek.txt
Vyrobte simulátor sněžení. 10x za sekundu se na horním řádku objeví nová vločka, všechny vločky se posunou o 3 px dolů a náhodně 0 2 px doleva nebo doprava.
namespace Sněžení public partial class oknoprogramu : Form Random náhoda = new Random(); List<Point> seznamvloček = new List<Point>(); public oknoprogramu() InitializeComponent(); private void oknoprogramu_paint(object sender, PaintEventArgs e) Graphics kp = e.graphics; foreach (Point vločka in seznamvloček) kp.fillrectangle(brushes.white, vločka.x, vločka.y, 2, 2); private void časovač_tick(object sender, EventArgs e) // Jedna nová vločka int maxx = ClientSize.Width - 1; int x = náhoda.next(0, maxx+1); Point novávločka = new Point(x, 0); seznamvloček.add(novávločka); // Posuň všechny vločky for (int index = 0; index < seznamvloček.count; index++) int posunx = náhoda.next(-2, +2+1); int posuny = 3; int novéx = seznamvloček[index].x + posunx; int novéy = seznamvloček[index].y + posuny; seznamvloček[index] = new Point(novéX, novéy); Refresh(); // Pro jednoduchost se zde neřeší odstraňování vloček, // které zapadly pod spodní okraj, ze seznamu
Vyrobte jednoduchý souborový manažer, který dokáže zobrazovat obsah disků. Disky a složky vybírejte a zobrazujte prvkem listbox. Využijte metody třídy Path a Directory.
using System; using System.IO; using System.Windows.Forms; namespace Souborový_manažer public partial class oknoprogramu : Form int početpodsložek = 0; public oknoprogramu() InitializeComponent(); private void oknoprogramu_load(object sender, EventArgs e) // Načti seznam složek string[] seznamdisků = Environment.GetLogicalDrives(); foreach (string disk in seznamdisků) listboxvýběrdisku.items.add(disk); private void obalistboxy_selectedindexchanged(object sender, EventArgs e) // Zobrazená složka a vybrané prvky listboxů string zobrazenásložka = polezobrazenásložka.text; int indexvybranéhodisku = listboxvýběrdisku.selectedindex; int indexvybranépodsložky = listboxobsahsložky.selectedindex; // Jakou složku zobrazit? string novásložka; if (sender == listboxvýběrdisku) // vybrán disk, zobraz kořenovou složku novásložka = listboxvýběrdisku.items[indexvybranéhodisku].tostring(); else if (indexvybranépodsložky >= početpodsložek) // není vybrána podsložka, ale soubor return; else string vybranápodsložka = listboxobsahsložky.items[indexvybranépodsložky].tostring(); if (vybranápodsložka == "..") // vybrána rodičovská složka novásložka = Path.GetDirectoryName(zobrazenáSložka); else // vybrána podsložka novásložka = Path.Combine(zobrazenáSložka, vybranápodsložka); polezobrazenásložka.text = novásložka; try seznampodsložek = Directory.GetDirectories(nováSložka); catch seznampodsložek = new string[0]; foreach (string podsložka in seznampodsložek) string bezcesty = Path.GetFileName(podsložka); listboxobsahsložky.items.add(bezcesty.toupper()); // Počet podsložek včetně případné rodičovské početpodsložek = listboxobsahsložky.items.count; // Načti soubory string[] seznamsouborů; try seznamsouborů = Directory.GetFiles(nováSložka); catch seznamsouborů = new string[0]; foreach (string soubor in seznamsouborů) string bezcesty = Path.GetFileName(soubor); listboxobsahsložky.items.add(bezcesty.tolower()); // Začni odkazem na rodičovskou složku listboxobsahsložky.items.clear(); if (Path.GetDirectoryName(nováSložka)!= null) // nejsme na kořeni listboxobsahsložky.items.add(".."); // Načti podsložky string[] seznampodsložek;
Načtení celého souboru velmi časté, proto pro to existuje metoda ReadAllLines Výběr více prvků v listboxu vlastnost SelectionMode nastavit na MultiExtended vybrané prvky lze zjistit pomocí jejich indexů v poli dostupném pod vlastností SelectedIndices. Alternativně i dotazem na SelectedItems.
private void tlačítkoprocházet_click(object sender, EventArgs e) if (oknootevřenísouboru.showdialog() == DialogResult.OK) polejménosouboru.text = oknootevřenísouboru.filename; private void tlačítkonačtiseznam_click(object sender, EventArgs e) // Vymaže stávající položky seznamu listbox.items.clear(); // Načte seznam ze souboru do listboxu try StreamReader soubor = new StreamReader(poleJménoSouboru.Text, Encoding.Default); string řádek; while ((řádek = soubor.readline())!= null) listbox.items.add(řádek); soubor.close(); catch MessageBox.Show("Chyba při načítání seznamu", "CHYBA"); private void tlačítkovypišvybrané_click(object sender, EventArgs e) var poleindexů = listbox.selectedindices; string zpráva = "Vybráno:" + Environment.NewLine; foreach (int index in poleindexů) zpráva += listbox.items[index].tostring() + Environment.NewLine; MessageBox.Show(zpráva);
Kreslení mimo Paint - např. v obsluze stisku tlačítka apod. Graphics kp = CreateGraphics(); kp.fillrectangle(brushes.red, 10, 10, 20, 20); kp.dispose(); Refresh se už nevolá. Paint ale vynechat nelze, jinak program nebude fungovat např. po minimalizaci, překrytí a odkrytí jiným oknem apod.