Wykorzystanie komponentu Timer i kontrolki PictureBox
Stronę tą wyświetlono już: 2062 razy
Tym razem stworzę kolejny prosty projekt programu o nazwie Zegar. Chyba nazwa jest na tyle jasna, że wiadomo co ten program będzie robił. Dzięki temu projektowi poznamy podstawy rysowania, tworzenia bitmapy, wykorzystania kontrolki PictureBox oraz komponentu Timer.

W właściwościach okna głównego programu należy zmienić pole (Name) z Form1 na Zegar i to samo należy uczynić z polem Text. Również rozmiar okna Size powinien zostać ustawiony na 312; 336. Tę samą wartość przypisać należy do pola MaximumSize i MinimumSize, co zablokuje możliwość zmiany wymiarów okna programu.
Warto też zmienić nieco właściwości wstawionej kontrolki PictureBox. Tak więc dla pola (Name) wpisać pb_drawing.
Kod programu należy zmodyfikować w następujący sposób:
- namespace Zegar
- {
- public partial class Zegar : Form
- {
- System.DateTime t; // zmienna, która będzie przechowywała czas
- Graphics gr; // interfejs graficzny do rysowania
- Bitmap bmp; // bitmapa, na której zegar będzie rysowany
- public Zegar()
- {
- InitializeComponent();
- t = System.DateTime.Now; // pobieranie aktualnego czasu
- timer1.Interval = 1000; // interwał dla zegara w milisekundach
- timer1.Start(); // uruchomienie zegara
- bmp = new Bitmap(300, 300); // tworzenie bitmapy 300 na 300 px (bo na cóż nam większa)
- gr = Graphics.FromImage(bmp); // tworzenie kontekstu graficznego, który będzie powiązany z otrzymaną bitmapą
- }
- private void DrawCircle(int xc, int yc, int ray, Color fill, Color pen) // a to będzie funkcja rysująca okręgi
- {
- Brush b = new SolidBrush(fill); // tak się tworzy wypełnienie
- gr.FillEllipse(b, xc - ray, yc - ray, 2 * ray, 2 * ray); // tak się rysuje wypełnioną elipsę
- Pen p = new Pen(pen, 2); // tak się tworzy pędzel
- gr.DrawEllipse(p, xc - ray, yc - ray, 2 * ray, 2 * ray); // a tak się rysuje obrys elipsy
- b.Dispose(); // zwalnianie wypełnienia
- p.Dispose(); // zwalnianie pędzla
- }
- }
- }
Dodać należy dwa zdarzenia, pierwsze dotyczące kontrolki pb_drawing dotyczyć będzie odrysowania Paint:
- private void pb_drawing_Paint(object sender, PaintEventArgs e)
- {
- DrawCircle(150, 150, 130, Color.FromArgb(255, 220, 220, 220), Color.FromArgb(255, 150, 150, 150));
- DrawCircle(150, 150, 120, Color.FromArgb(255, 255, 255, 255), Color.FromArgb(255, 150, 150, 150));
- int ray = 100;
- for (int i = 0; i < 12; i++) // Rysowanie punktów skali godzin
- {
- double angle = Math.PI / 6 * i; // wyliczanie kąta dla danej godziny (i = 0 - oznacza godzinę 0 lub 12; i = 1 - oznacza godzinę 1 lub 13 itd
- int x = (int)(150 + ray * Math.Sin(angle)); // obliczanie współrzędnej x
- int y = (int)(150 + ray * Math.Cos(angle)); // obliczanie współrzędnej y
- DrawCircle(x, y, 5, Color.Black, Color.Black); // rysowanie okręgu
- }
- for (int i = 0; i < 60; i++) // Rysowanie punktów skali sekundnika i minutnika
- {
- double angle = Math.PI / 30 * i;
- int x = (int)(150 + ray * Math.Sin(angle));
- int y = (int)(150 + ray * Math.Cos(angle));
- DrawCircle(x, y, 2, Color.White, Color.Black);
- }
- // Rysowanie wskazówki godzin
- Pen p = new Pen(Color.Black, 3);
- ray = 50;
- double angle2 = (double)((this.t.Hour % 12) * 60 + t.Minute) / 360.0 * Math.PI;
- gr.DrawLine(p, 150, 150, (int)(150 + ray * Math.Sin(angle2)), (int)(150 - ray * Math.Cos(angle2)));
- // Rysowanie wskazówki minut
- p.Dispose();
- p = new Pen(Color.Black, 2);
- angle2 = (double)(t.Minute * 60 + t.Minute) / 1800.0 * Math.PI;
- ray = 80;
- gr.DrawLine(p, 150, 150, (int)(150 + ray * Math.Sin(angle2)), (int)(150 - ray * Math.Cos(angle2)));
- // Rysowanie wskazówki sekund
- p.Dispose();
- p = new Pen(Color.Black, 1);
- angle2 = (double)t.Second / 30.0 * Math.PI;
- ray = 80;
- gr.DrawLine(p, 150, 150, (int)(150 + ray * Math.Sin(angle2)), (int)(150 - ray * Math.Cos(angle2)));
- p.Dispose();
- e.Graphics.DrawImage(bmp, new Point(0, 0));
- }
Drugie zdarzenie związane jest z komponentem Timer, które przyjmuje nazwę Tick:
- private void timer1_Tick(object sender, EventArgs e)
- {
- t = System.DateTime.Now;
- this.pb_drawing.Invalidate();
- }
Teraz pozostało już tylko najtrudniejsze, czyli wciśnięcie F5, co powinno spowodować pojawienie się okna programu jak na poniższym rysunku.


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