Commander w C#

Commander w C#

Autor: Marcin Hałaczkiewicz

Opublikowano: 4/24/2007, 12:00 AM

Liczba odsłon: 94752

Dziś napiszemy program przypominający Windows Commandera, Total Commandera czy rządzącego w czasach DOS-a Norton Commandera. Innymi słowy nasza aplikacja będzie służyć do przeglądania zawartości dysków (płyt), dyskietek. Będzie umożliwiać również podstawowe operacje na plikach i folderach, tzn. kopiowanie, przenoszenie oraz usuwanie.

Zaczynamy od stworzenia nowego projektu, który nazywamy Commander. Nazwę formy oraz pliku z nią (Form1.cs) zmieniamy na frmCommander. Ustawiamy rozmiar oraz minimalny rozmiar (Size i MinimumSize) na 433;371. We właściwości Text wpisujemy Commander. Do formy dodajemy dwie kontrolki ListView. Nazywamy je lvOkno1 i lvOkno2. Rozmiary obydwu zmieniamy na 200;250. Lokalizacja pierwszego okna to 12;42, a drugiego 215;42. W obu kontrolkach ustawiamy HideSelection na False - dzięki temu po utracie "focusu" przez kontrolkę nadal będzie widoczne, który element jest zaznaczony (niebieskie zaznaczenie nie zniknie). Również dla obu kontrolek ustawiamy View na Details oraz FullRowSelect na true. Spowoduje to wyświetlanie elementów okien w widoku szczegółowym oraz to, że po wybraniu wiersza, będzie on cały zaznaczony na niebiesko, a także możliwość wybrania wiersza po kliknięciu w dowolne jego miejsce, a nie tylko na szerokości pierwszej kolumny. Aby stworzyć poszczególne pionowe sekcje widoku szczegółowego (dla obu okien będą takie same) klikamy na wielokropek we właściwości Columns i za pomocą przycisku Add dodajemy trzy kolumny i kolejno zmieniamy ich właściwość Text na Nazwa, Typ oraz Rozmiar. Zmieńmy jeszcze właściwości Anchor: lewego okna na Top, Bottom, Left, a prawego na Top, Bottom, Right. Spowoduje to trzymanie się kontrolek odpowiednich boków podczas rozciągania formy.

W oknach, które przed chwilą stworzyliśmy będą wyświetlać się zawartości dysków. Stwórzmy teraz element, który pozwoli wybrać napęd. Dodajemy do formy dwie kontrolki ComboBox. Nazwijmy je Dysk1 oraz Dysk2. Rozmiar zostawiamy domyślny, zmieniamy położenie na 12;12 dla pierwszej oraz na 215;12 dla drugiej. Ponadto dla Dysk2 zmieniamy Anchor na Top, aby ComboBox trzymał się jedynie górnej krawędzi podczas rozciągania.

Z wyglądu formy pozostały nam jeszcze jedynie przyciski. Tworzymy cztery i zmieniamy ich nazwy na kolejno: cmdOtworz, cmdKopiuj, cmdPrzenies oraz cmdUsun, a położenia na kolejno: 12;298, 112;298, 215;298 i 315;298. Rozmiary wszystkich przycisków ustawiamy na 100;35, a właściwość Anchor na Bottom. W polu Text będziemy wpisywać w dwóch linijkach, aby było to możliwe, przed rozpoczęciem wpisywania tekstu musimy kliknąć na strzałce przy właściwości Text. W drugiej linijce znajdzie się nazwa klawisza funkcyjnego. Wpisujemy kolejno: Otwórz wciskamy na klawiaturze enter oraz dopisujemy tekst F5, dla drugiego przycisku wpisujemy  Kopiuj <enter> F6, dla trzeciego: Przenieś <enter> F7 oraz dla ostatniego: Usuń <enter> F8.

To tyle jeśli chodzi o wygląd aplikacji (no może nie do końca, ale o tym później). Zajmijmy się funkcjonalnością programu. Dodajemy do klasy z formą sześć zmiennych pomocniczych, których funkcje odpowiadają ich nazwom. Są to:

private ListView AktywneOkno = null;
private string AktywnaSciezka;
private ListView NieAktywneOkno = null;
private string NieAktywnaSciezka;
private string sciezka1 = "C:\\"; // sciezka dla lvOkno1
private string sciezka2 = "C:\\"; // sciezka dla lvOkno2

Napiszmy teraz w klasie z formą dwie przydatne funkcje: void wyswietl(ListView gdzie, string katalog) oraz void KopiujKatalog(string zrodlo, string cel). Pierwsza z nich wyświetli zawartość katalogu przekazanego w drugim argumencie w oknie ListView przekazanym w pierwszym argumencie. Jeśli znajdujemy się głębiej niż tylko na dysku (np. C:\Windows) to u góry zostanie wyświetlone ...,  co pozwoli nam wrócić do katalogu znajdującego się wyżej w hierarchii. Dla plików w kolumnie Typ pojawi się rozszerzenie pliku, dla katalogów znajdzie się tam napis <DIR>. Kolumna Rozmiar będzie wypełniona jedynie w przypadku pliku.

Niestety programiści Microsoftu nie pomyśleli o funkcji pozwalającej skopiować katalog. Musimy więc zająć się tym sami. Zajmie się tym funkcja void KopiujKatalog(string zrodlo, string cel). Działa ona w sposób rekurencyjny. Oznacza to, że jeśli kopiowany katalog zawiera podfoldery, to z poziomu kopiowania tego właśnie katalogu zostanie wywołana funkcja do skopiowania podfolderu. KopiujKatalog sprawdza kolejno elementy kopiowanej "teczki". Jeśli tym elementem jest folder, to KopiujKatalog skopiuje go rekurencyjnie wywołując samą siebie, jeśli jest to plik - dokona się zwyczajne kopiowanie. Niby nic wielkiego, jednak Microsoft na to nie wpadł ;)

Stwórzmy teraz obsługę zdarzenia FormLoad dla naszej formy. Pobierze ono litery wszystkich dostępnych w systemie dysków, oraz pozwoli wybrać je w kontrolkach Dysk1 i Dysk2. Ponadto dla każdej z nich spowoduje aktywację "C:\", co w konsekwencji sprawi, że zawartość tego dysku wyświetli się w oknach (zaraz napiszemy zdarzenie, które to obsłuży).

Gdy zakończyliśmy projektowanie wyglądu aplikacji zostało powiedziane, że to jeszcze nie wszystko. Chodzi o to, że podczas zmieniania rozmiaru okna programu, kontrolki nie rozszerzają się dokładnie tak jakbyśmy sobie tego życzyli. Najlepiej by było, gdyby okna ListView były jednakowych rozmiarów i spotykały się na środku formy z takim samym odstępem jak po uruchomieniu aplikacji. Zapewnimy to wszystko oprogramowując zdarzenie FormResize dla formy. W jego kodzie obliczane są odpowiednie rozmiary oraz położenia okien lvOkno1 i lvOkno2.

Chcielibyśmy, aby po wybraniu dysku z ComboBoxa uaktualniło się odpowiednie okno. W tym celu dodajemy dwa zdarzenia SelectedIndexChanged dla obu kontrolek ComboBox. Będą działać one dokładnie tak samo z tym, że dla odpowiednich okien i ComboBoxów. Spowodują wyświetlenie nowo wybranego napędu we właściwym oknie lub ewentualnie wyświetlą komunikat o błędzie, gdy np. w cd-romie nie ma płyty.

Wcześniej stworzyliśmy zmienne pomocnicze przechowujące aktywne/nieaktywne ścieżki i okna. Aby zapewnić ich poprawną zawartość tworzymy dwa zdarzenia Enter dla kontrolek lvOkno1 i lvOkno2. Spowodują one odpowiednie uaktualnienie zmiennych pomocniczych w zależności od tego jakie okno zostało wybrane (czyli stało się aktywne). Przyda się to podczas kopiowania i przenoszenia. Operacje te będą się odbywać z aktywnego do nieaktywnego ListView'a.

Zajmijmy się teraz nawigacją okien. W tym celu stwórzmy dwa zdarzenia KeyDown oraz MouseDoubleClick dla kontrolek lvOkno1 i lvOkno2. Nie róbmy tego jednak w standardowy sposób, tj. klikając dwa razy na odpowiednim zdarzeniu na liście zdarzeń. Wpiszmy nazwy ręcznie - dla obu okien tak samo. Dla MouseDoubleClick będzie to lvOkno_MouseDoubleClick, a dla KeyDown - lvOkno_KeyDown. Zdarzenia różnią się jedynie "głównym if-em", który dla MouseDoubleClick sprawdza czy kliknęliśmy lewym przyciskiem, a dla KeyDown - czy wcisnęliśmy Enter. Wnętrze if-a sprawdza czy chcemy przejść do katalogu wyżej (element "..."), przejść do nowego katalogu czy otworzyć plik i odpowiednio reaguje na naszą akcję. Tzn. przechodzi poziom wyżej, wyświetla zawartość nowego katalogu lub próbuje otworzyć plik (w przypadku niepowodzenia zostanie wyświetlony komunikat o błędzie).

Pozostało nam jedynie oprogramowanie kliknięć na przyciski. cmdOtworz_Click sprawdzi czy został wybrany dokładnie jeden element. Jeśli tak, zachowa się tak samo jak naciśnięcie Enter lub podwójne kliknięcie na elemencie, czyli otworzy go w odpowiedni dla jego typu sposób. cmdKopiuj_Click spowoduje przekopiowanie wszystkich zaznaczonych elementów z aktywnego okna do bieżącego katalogu w oknie nieaktywnym. Oczywiście inną funkcję wywoła dla katalogów, a inną dla plików. Po wszystkim zaktualizuje zawartość nieaktywnego okna, czyli tego, do którego kopiowaliśmy. cmdPrzenies_Click robi to samo, ale po skopiowaniu kasuje pliki, które kopiowaliśmy, czyli de facto je przenosi. Ostatnie zdarzenie cmdUsun_Click nie spowoduje nic innego jak usunięcie zaznaczonych elementów. Wcześniej poprosi nas o potwierdzenie wyboru, a po wszystkim zaktualizuje zawartość odpowiedniego okna.

Na koniec pozostało jedynie zdarzenie Click dla formy. Jeśli został naciśnięty któryś z klawiszy funkcyjnych (zgodnie z etykietami na przyciskach) to zostanie podjęta odpowiednia akcja. I tak oto nasz programik jest ukończony. Jest całkiem funkcjonalny i może posłużyć w zastępstwie niezbyt lubianego eksploratora w Windows. Oczywiście do "prawdziwego" programu trochę mu brakuje. Można by go wyposażyć w wiele innych opcji, jak choćby połączenie ftp, czy zwykłe Zmień Nazwę. Zachęcam do samodzielnego eksperymentowania.

Jak wykorzystać Copilot w codziennej pracy? Kurs w przedsprzedaży
Jak wykorzystać Copilot w codziennej pracy? Kurs w przedsprzedaży

Wydarzenia