Wykorzystanie kontrolek NumericUpDown, ProgressBar, komponentu okna dialogowego FolderBrowserDialog oraz użycie wątków
Stronę tą wyświetlono już: 1802 razy
Stwórzmy czym prędzej nowy projekt programu ImageResize, który będzie służył do generowania miniatur zdjęć znajdujących się w podanej lokalizacji i zapisywanie ich do specjalnie utworzonego folderu o nazwie sm_img. Na poniższym rysunku pokazany został widok okna programu.

Ustawienie właściwości okna głównego (nr. 1 na rysunku 1):
- (Name) - ImCreator;
- Text - ImCreator;
- MinimumSize - 799; 265;
- MaximumSize - 799; 265;
- Size - 799; 265.
Kontrolka TextBox (nr. 2 na rysunku 1):
- (Name) - tb_path;
- Location - 7; 35;
- Size - 746; 20
Kontrolka Button (nr. 3 na rysunku 1):
- (Name) - bt_browse;
- Location - 754; 35;
- Size - 25; 19
Kontrolka NumericUpDown (nr. 4 na rysunku 1):
- (Name) - n_maxsize;
- Maximum - 2000;
- Minimum - 10;
- Value - 800;
- Location - 189; 70;
- Size - 120; 20
Kontrolka Button (nr. 5 na rysunku 1):
- (Name) - CreateImg;
- Location - 7; 107;
- Size - 771; 25
Kontrolka Label (nr. 6 na rysunku 1):
- (Name) - lb_progress;
- Text - Postęp;
- Location - 11; 144;
- Size - 40; 13
Kontrolka ProgressBar (nr. 7 na rysunku 1):
- (Name) - pb_progress;
- Location - 7; 169;
- Size - 770; 48;
Komponent FolderBrowserDialog (nr. 8 na rysunku 1):
- (Name) - fb_dialog;
Tekst i rozmieszczenie dwóch pozostałych kontrolek Label widoczne jest na rysunku 1, toteż ich nie opisuję.
Pod kontrolkę 3 podpiąć należy zdarzenie Click:
- private void bt_browse_Click(object sender, EventArgs e)
- {
- if (fb_dialog.ShowDialog() == DialogResult.OK) // wyświetlenie okna dialogowego Folder Browser i sprawdzenie, czy wciśnięto przycisk OK
- {
- tb_path.Text = fb_dialog.SelectedPath; // jeżeli przycisk OK został wciśnięty to pobrać należy ścieżkę do wskazanego folderu
- }
- }
Kontrolka 5 na rysunku 1 powinna zostać podpięta pod zdarzenie Click:
- private void CreateImg_Click(object sender, EventArgs e)
- {
- System.Threading.Thread thr = new System.Threading.Thread(CreateImgFu); // tworzenie nowego obiektu wątku, parametrem konstruktora jest delegat CreateImgFu
- thr.Start(); // uruchomienie wątku
- }
Jak widać w powyższym kodzie tworzę nowy wątek i go uruchamiam. Wątkiem tym będzie działanie wewnątrz metody CreateImgFu, której kod będzie wyglądał następująco:
- private void CreateImgFu()
- {
- EnableWnd(false); // blokowanie okna głównego, tak aby użytkownik nie mógł w nim klikać niczego
- if (System.IO.Directory.Exists(tb_path.Text)) // sprawdzanie poprawności ścieżki
- {
- string[] files_jpg = System.IO.Directory.GetFiles(tb_path.Text + (char)(92), "*.jpg"); // pobieranie listy plików jpg
- System.IO.Directory.CreateDirectory(tb_path.Text + "\\sm_img"); // tworzenie nowego folderu
- int counting = 0; // licznik przetworzonych obrazów
- foreach (string i in files_jpg) // iterowanko po ścieżkach dostępu
- {
- SetProgressValue( counting * 100 / files_jpg.Length); // ustawianie paska postępu
- SetProgressText("Przetwarzanie pliku: " + i); // ustawianie tekstu opisującego plik, kótry aktualnie jest przetwarzany
- if (System.IO.File.Exists(tb_path.Text + "\\sm_img" + (char)(92) + GetFileName(i))) // jeżeli dany plik już istnieje to nie chcemy go nadpisywać
- {
- continue; // więc przechodzimy do następnej iteracji bez wykonywania dalszego kodu pętli
- }
- Image img = Image.FromFile(i); // wczytywanie obrazka z pliku
- int max_size = (int)n_maxsize.Value; // pobieranie maksymalnego rozmiaru
- double k = (double)max_size / (double)(img.Width < img.Height ? img.Height : img.Width); // ustalanie współczynnika skali
- int width = (int)(img.Width * k); // obliczanie szerokości obrazu docelowego
- int height = (int)(img.Height * k); // obliczanie wysokości obrazu docelowego
- if (width > 0 && height > 0) // sprawdzanie, czy otrzymane wartości nie są czasem mniejsze lub równe 0
- {
- Bitmap bmp = new Bitmap(img, width, height); // tworzę bitmapę na podstawie obrazka o podanych wymiarach
- bmp.Save(tb_path.Text + "\\sm_img" + (char)(92) + GetFileName(i), System.Drawing.Imaging.ImageFormat.Jpeg); // zapisuję obrazek z kompresją Jpeg
- }
- counting++; // zwiększam licznik o 1
- }
- SetProgressValue(100); // na koniec progress bar na 100 ustawiam
- }
- EnableWnd(true); // odblokowuję okno
- }
W powyższym kodzie użyłem czterech dodatkowych metod, gdzie trzy z nich są wymagane w celu uzyskania dostępu do zmiennych w nowo utworzonym wątku. Kod źródłowy tych metod jest następujący:
- private string GetFileName(string mpath) // wyciąganie nazwy pliku z podanej ścieżki
- {
- int index = mpath.LastIndexOf((char)(92));
- string s = mpath.Substring(index + 1);
- return s;
- }
- private void EnableWnd(bool value) // włączanie / wyłączanie aktywności okna
- {
- if (InvokeRequired) // jeżeli metoda została wywołana w innym wątku niż w tym, w którym została utworzona to
- {
- Invoke(new Action<bool>(EnableWnd), value); // trzeba skorzystać z metody Invoke
- }
- else
- {
- Enabled = value;
- }
- }
- private void SetProgressText(string text)
- {
- if (InvokeRequired)
- {
- Invoke(new Action<string>(SetProgressText), text);
- }
- else
- {
- lb_progress.Text = text;
- }
- }
- private void SetProgressValue(int value)
- {
- if (InvokeRequired)
- {
- Invoke(new Action<int>(SetProgressValue), value);
- }
- else
- {
- pb_progress.Value = value;
- }
- }
Najtrudniejsze na sam koniec, czyli kompilacja programu i jego uruchomienie.


Tytuł:
Wzorce projektowe w .NET Core 3. Projektowanie zorientowane obiektowo z wykorzystaniem C# i F#
Autor:
Dmitri Nesteruk

Tytuł:
Jak pisać świetne gry 2D w Unity. Niezależne programowanie w języku C#
Autor:
Jared Halpern

Tytuł:
C# 9.0 w pigułce
Autor:
Joseph Albahari

Tytuł:
C# 9.0. Leksykon kieszonkowy
Autor:
Joseph Albahari, Ben Albahari

Tytuł:
C# 8.0. Kompletny przewodnik dla praktyków. Wydanie VII
Autor:
Mark Michaelis

Tytuł:
C# 8.0 w pigułce
Autor:
Joseph Albahari, Eric Johannsen

Tytuł:
Asynchroniczność i wielowątkowość w języku C#
Autor:
Grzegorz Lang

Tytuł:
C# 8.0. Programowanie. Tworzenie aplikacji Windows, internetowych oraz biurowych
Autor:
Ian Griffiths

Tytuł:
C# 8.0. Leksykon kieszonkowy
Autor:
Joseph Albahari, Ben Albahari

Tytuł:
Wzorce projektowe w .NET. Projektowanie zorientowane obiektowo z wykorzystaniem C# i F#
Autor:
Dmitri Nesteruk