Table of Contents
Strom se soubory
Na záložce Files zobrazíme jednotlivé disky a jejich adresáře a soubory.
Kliknutím na některé soubory zobrazíme odpovídající panel
Podadresáře budeme načítat průběžně podle toho, které adresáře si uživatel bude prohlížet.
Aby byly vidět značky naznačující, že prvek stromu má v sobě schované další větve,
načteme do stromu o úroveň (o patro) prvků více než uživatel dosud navštívil.
Třída FileNode
Rozšíříme standardní třídu TreeNode o proměnnou path skladující kompletní cestu k souboru,
a proměnou ready obsahující příznak, zda byly nacteny i podadresáře daného uzlu.
class FileNode : TreeNode { public string path; public bool ready = false; // true ... podadresare jiz nacteny }
Jednotlivé disky
Metoda displayDrives
- Vymažeme původní obsah stromu
- Statická funkce GetDrives ve třídě DriveInfo nám poskytne pole informací o jednotlivých discích ( C:, D:, … )
- V cyklu projedeme pole disků
- Pro jednotlivé disky zavoláme metodu displayDirectory
- první parametr bude podobjekt Nodes ve stromu, tím budeme přidávat disky jako větve stromu na nejvyšší úrovni
- druhým parametrem bude informace o kořenovém adresáři disku
private void displayDrives () { fileTree.Nodes.Clear (); DriveInfo[] roots = DriveInfo.GetDrives (); foreach (DriveInfo r in roots) displayDirectory (fileTree.Nodes, r.RootDirectory); }
Zobrazení adresáře souborů ve stromu
Metoda displayDirectory
- má za první parametr objekt typpu “kolekce” uzlů, do které budeme přidávat nový uzel
- druhý parametr typu DirectoryInfo poskytne informace o adres85i na disku
- parametr level určuje kolik pater do stromu přidáme
- Vytvoříme nový uzel našeho typu FileNode
- do node.path uložíme cestu k adresáři
- node.ready nastavíme na false, podadresáře ještě nejsou načteny
- v node.Text bude text zobrazovaný v daném uzlu, uložíme tam jen krátké jméno adresáře bez nadřazených adresářů
- do ToolTipText, textu v malém obdélníčku (pokud se na chilku zastavíme s myší), bude úplná cesta k adresáři
- ForeColor určuje barvu textu
- target.Add (node); přidá nový uzel do příslušného místa stromu
- metoda displayDetail, popsaná dále, doplní pod nový uzel další adresáře a soubory
private void displayDirectory (TreeNodeCollection target, DirectoryInfo dir, int levels = 2) { FileNode node = new FileNode (); node.path = dir.FullName; node.ready = false; node.Text = dir.Name; node.ToolTipText = node.path; node.ForeColor = Color.Blue; target.Add (node); displayDetail (node, dir, levels); }
Zobrazení souboru ve stromu
Metoda displayFile obdoně zobrazí informace o jednom souboru.
Standardní třida FileInfo také může poskytnout informace o délce a datumu souboru
private void displayFile (TreeNodeCollection target, FileInfo f) { FileNode node = new FileNode (); node.path = f.FullName; node.ready = true; node.Text = f.Name; node.ToolTipText = node.path; node.ForeColor = Color.Orange; target.Add (node); }
Soubory a podadresáře
Metoda displayDetail
- dostane jako parametr již existující uzel stromu node
- a v tomto uzlu je již zobrazeno jméno adresáře dir
- poslední parametr určuje kolik pater je ještě potřeba zobrazit
- Pokud je level větší než jedna, budeme pokračovat
- Blok try … catch má zachytit výjimky, například nedovolený přístup do adresáře nebo disk bez CD/DVD média
- dir.GetFiles () poskytne pole s popisy jednotlivý souborů, zavoláme pro ně metodu displayFile
- dir.GetDirectories () zjistí seznam podadresářů, funkci displayDirectory zavoláme pro počet pater o zmenšený o jedna
- Pokud vznikne výjimka
- informace o výjimce budou v proměnné e typu Exception
- vytvoříme uzel stromu (jen typu TreNode nikoliv FileNode)
- jako Text přidáme zprávu o výjimce e.ToString ()
- v plovoucím obdélníčku zobrazíme seznam právě prováděných funkcí e.ToString ()
- text obarvíme na červeno a přídáme do stromu
private void displayDetail (FileNode node, DirectoryInfo dir, int levels) { if (levels > 1) try { foreach (FileInfo f in dir.GetFiles ()) displayFile (node.Nodes, f); foreach (DirectoryInfo d in dir.GetDirectories ()) displayDirectory (node.Nodes, d, levels - 1); node.ready = true; } catch (Exception e) { TreeNode t = new TreeNode (); t.Text = e.ToString (); t.ToolTipText = e.StackTrace; t.ForeColor = Color.Red; node.Nodes.Add (t); } }
Rozvinutí větve představující adresář
Pokud uživatel “rozklikne” v2tev stromu, dřive než uvidí výsledek, tak proběhne treeView_BeforeExpand
V parametru e se skrývá odkaz na otvíranou větev e.Node, \ ta by již měla být dobře zobrazena, my se podíváme na dosud skryté pod poduzly e.Node.Nodes.
Poduzly přetypujeme na FileNode
FileNode node = n as FileNode;
pokud by n bylo jen TreeNode (např. červená zpráva o chybě), bude node rovno null.
Pro jednotlivé poduzly nám standardní třída DirectoryInfoposkytne informace o adresáři na disku new DirectoryInfo (node.path)
Pokud by při tom vznikla výjimka, přidáme try … catch
DirectoryInfo dir = new DirectoryInfo (node.path);
Nakonec funkce displayDetail přidá do stromu vnořené adresáře a soubory
private void treeView_BeforeExpand (object sender, TreeViewCancelEventArgs e) { foreach (TreeNode n in e.Node.Nodes) { FileNode node = n as FileNode; if (node != null && !node.ready) { try { DirectoryInfo dir = new DirectoryInfo (node.path); displayDetail (node, dir, 2); } catch (Exception ex) { } } } }
Výběr souboru ve stromu
Při dvojitém kliknutí do stromu pomocí FileInfo získáme příponu souboru a pro některé přípony zobrazíme panel
private void fileTree_DoubleClick (object sender, EventArgs e) { TreeNode node = fileTree.SelectedNode as TreeNode; if (node != null) { string path = node.FullPath; FileInfo f = new FileInfo (path); string ext = f.Extension; statusLabel.Text = path + ", " + ext; switch (ext) { case ".txt": case ".bat": case ".ini": case ".cs": case ".c": case ".cpp": case ".cc": case ".h": case ".hpp": displayText (path); break; case ".png": case ".bmp": case ".jpg": case ".jpeg": displayImage (path); break; case ".csv": displayTable (path); break; case ".chart": displayChart (path); break; case ".html": displayHtml (path); break; } } }
Funkce displayText vytvoří nový panel TextArea a zavolá dále popsanou funkci displayObject
public void displayText (string path) { TextArea a = new TextArea (path); displayObject (a); } public void displayImage (string path) { ImageArea a = new ImageArea (path); displayObject (a); } public void displayTable (string path) { TableArea a = new TableArea (path); displayObject (a); } public void displayChart (string path) { ChartArea a = new ChartArea (path); displayObject (a); } public void displayHtml (string path) { HtmlArea a = new HtmlArea (path); displayObject (a); }
Zobrazení nového panelu (nebo jiného objektu)
Na záložku Tree přidáme informace o novém objektu * jako text ve stromu použijeme standardní konverzi obj.ToString (), kterou používá i sčítání řetězců znaků * do standardní položky node.Tag typu object schováme ukazatel na objekt
Pokud je objekt typu Control nebo třídy z Control odvozené,
umístíme objekt nad pictureBox.
BringToFront umístí objekt nad jiné plouvoucí panely, aby byl vidět
public void displayObject (object obj) { TreeNode node = new TreeNode (); node.Text = obj.ToString (); node.Tag = obj; tree.Nodes.Add (node); if (obj is Control) { Control c = obj as Control; c.Parent = pictureBox; c.BringToFront (); } }
Kliknutí do stromu na záložce Tree
- Z uzlu stromu z položky Tag vyzvedneme ukazatel na objekt
- PropertyGrid na pravé straně okna zobrazí jednotlivé vlastnosti objektu
- Pokud je náš objekt plovoucím objektem nad původním obrázkem, umístíme objekt nad jiné objekty
private void tree_AfterSelect (object sender, TreeViewEventArgs e) { object obj = e.Node.Tag; propGrid.SelectedObject = obj; if (obj is Control) { Control c = obj as Control; c.BringToFront (); } }