Kolory postępu

W kolejnej części kursu C# zaprojektujemy własny komponent, w którym odtworzymy zasadnicze elementy standardowego paska postępu zaimplementowanego w klasie System.Windows.Forms.ProgressBar. Następnie uzupełnimy go o możliwość wyboru koloru. Nasz komponent pozwoli również na opcjonalne rysowanie gładkiego paska.

W kolejnej części kursu C# zaprojektujemy własny komponent, w którym odtworzymy zasadnicze elementy standardowego paska postępu zaimplementowanego w klasie System.Windows.Forms.ProgressBar. Następnie uzupełnimy go o możliwość wyboru koloru. Nasz komponent pozwoli również na opcjonalne rysowanie gładkiego paska.

Najprościej tworzyć komponent w otoczeniu projektu typu Windows Application, który będzie pełnił funkcję platformy testowej. Dlatego zaczynamy od utworzenia takiego projektu. Uruchamiamy Visual C i naciskamy kombinację klawiszy [Ctrl Shift N], co powoduje otwarcie okna New Project (rysunek 1). Na karcie Visual C# Projects na liście Templates wybieramy Windows Application, zmieniamy nazwę projektu (pole Name) na ColorProgressBarDemo i klikamy OK.

Rysunek 1. Zaczynamy od utworzenia projektu typu Windows Application.

Rysunek 1. Zaczynamy od utworzenia projektu typu Windows Application.

Teraz przechodzimy do tworzenia pliku, który będzie zawierał klasę implementującą kontrolkę. Otwieramy okno Add New Item, naciskając kombinację klawiszy [Ctrl Shift A]. Na karcie Local Project Items | UI (rysunek 2) zaznaczamy ikonę User Control. W polu Name ustalamy nazwę pliku na ColorProgressBar.cs i klikamy Open. Po chwili pojawi się widok projektowania nowego komponentu. Ustalamy rozmiar komponentu (w oknie własności lub bezpośrednio "łapkami" w podglądzie), ustawiając szerokość na 100 pikseli, a wysokość na 23 piksele. Jest to domyślny rozmiar komponentu ProgressBar. Widok projektowania umożliwia budowę interfejsu kontrolki z gotowych komponentów Windows Forms, tak jak projektuje się interfejs aplikacji. My jednak postąpimy inaczej - narysujemy pasek postępu na powierzchni kontrolki, korzystając z możliwości klasy Graphics związanej z klasą bazową naszego komponentu, tj. UserControl.

Zacznijmy od narysowania ramki imitującej efekt trójwymiarowości. Pozwoli nam to sprawdzić, czy komponent będzie widoczny w formie i czy możliwe będzie jego testowanie w ten sposób. Klikamy żółtą błyskawicę na pasku narzędzi okna własności i na liście zdarzeń odnajdujemy Paint. Następnie dwukrotnie klikamy związane z nim pole. Powstanie metoda zdarzeniowa ColorProgressBar_Paint, w której umieszczamy polecenia rysujące ramkę:

private void ColorProgressBar_Paint(

object sender

System.Windows.Forms.PaintEventArgs e)

{

BackColor = this.Parent.BackColor;

//brzegi

Pen cien = new Pen

(SystemColors.ControlDark);

Pen swiatlo =

new Pen(SystemColors.ControlLightLight);

e.Graphics.DrawLine(cien,0,Height-1,0,0);

e.Graphics.DrawLine(cien,0,0,Width-1,0);

e.Graphics.DrawLine(

swiatlo,Width-1,0,Width-1,Height-1);

e.Graphics.DrawLine(

swiatlo,Width-1,Height-1,0,Height-1);

}

Rysunek 2. Szablon User Control (kontrolka użytkownika) pozwala na projektowanie myszą w sposób identyczny, jak w wypadku formy.

Rysunek 2. Szablon User Control (kontrolka użytkownika) pozwala na projektowanie myszą w sposób identyczny, jak w wypadku formy.

Wracamy do widoku projektowania formy (karta Form1.cs [Design]). Na palecie My User Controls widoczny jest projektowany przez nas komponent ColorProgressBar. Zaznaczamy go i umieszczamy na powierzchni formy. Aby móc zobaczyć aktualny podgląd komponentu w widoku projektowania, należy go wcześ-niej skompilować. Naciśnijmy wobec tego kombinację klawiszy [Ctrl Shift B]. Komponent powinien być również widoczny po uruchomieniu aplikacji ([F5]).

Własności

Rysunek 3. Na podglądzie formy możemy umieścić dwa egzemplarze projektowanego komponentu (tu widoczne w gotowej postaci), standardowy pasek postępu dla porównania i suwak, który pozwoli na kontrolę własności Value wszystkich pasków.

Rysunek 3. Na podglądzie formy możemy umieścić dwa egzemplarze projektowanego komponentu (tu widoczne w gotowej postaci), standardowy pasek postępu dla porównania i suwak, który pozwoli na kontrolę własności Value wszystkich pasków.

Mając przygotowane środowisko testowania kontrolki, możemy już na poważnie zabrać się za jej projektowanie. Przede wszystkim pomyślmy, jakie powinna mieć własności. Obstawałbym przy tym, żeby projektując komponent zadbać o jego zgodność z komponentem System.Windows.Forms.ProgressBar. To ułatwi zamianę standardowego komponentu na opracowany przez nas w gotowych projektach. Powinniśmy zatem zdefiniować własności Value, Minimum, Maximum i Step obecne w pierwowzorze. Poza tym dodamy własność pozwalającą na określenie koloru paska postępu. Albo jeszcze lepiej dwie własności, ColorBegin i ColorEnd którymi będziemy mogli kontrolować dwa kolory - nasz pasek będzie stopniowo zmieniał barwę w podobny sposób, jak na pasku tytułu okna w nowych wersjach Windows. Dodamy także własność Smooth, określającą, czy pasek ma być ciągły, czy zbudowany z charakterystycznych prostokątów. Przejdźmy do definiowania własności (ten temat został już omówiony w wydaniu PCWK 9/2005 przy okazji definiowania struktury Complex). Zmieniamy kartę na ColorProgressBar.cs i do klasy ColorProgressBar dodajemy następujący blok instrukcji (pełny kod listingu na płycie):

#region Wlasnosci

private int _Minimum = 0;

private int _Maximum = 100;

private int _Value = 0;

private int _Step = 10;

private Color _ColorBegin = Color.Yellow;

private Color _ColorEnd = Color.Red;

private bool _Smooth;

public int Minimum {

get {return _Minimum;}

set {

if (value>_Maximum) value = _Maximum;

_Minimum = value;

Refresh(); }

}

public int Maximum {

get {return _Maximum;}

set {

if (value<_Minimum) value = _Minimum;

_Maximum = value;

Refresh(); }

}

public int Value {

get {return _Value;}

set {

if (value<_Minimum) value = _Minimum;

if (value>_Maximum) value = _Maximum;

_Value = value;

Refresh(); }

}

public int Step {

get {return _Step;}

set {_Step = value;}

}

public Color Color

Begin {

get {return _ColorBegin;}

set { _ColorBegin = value;

Refresh(); }

}

...

Naciśnijmy klawisze [Ctrl Shift B], aby skompilować projekt wraz z kontrolką. Jeżeli teraz przejdziemy na kartę Form1.cs [Design], to zaznaczając komponent w widoku projektowania, zobaczymy w oknie Properties dodane przed chwilą własności (rysunek 4). Proszę zwrócić uwagę, że wybierając jedną z własności w panelu na dole okna własności, zobaczymy opis zdefiniowany przez nas w atrybucie (umieszczonym w nawiasach kwadratowych) poprzedzającym zaznaczoną własność. Atrybut wskazuje także nazwę kategorii, w której ma się ona znaleźć (z powyższego listingu atrybuty opisujące własności zostały usunięte, ale są w kodach źródłowych na płycie).

Każda z dodanych do klasy Color-ProgressBar własności ma sekcje get i set. Wszystkie mogą być wobec tego zarówno odczytywane, jak i modyfikowane. Z każdą własnością związane jest prywatne pole, które przechowuje wartości (przyjąłem konwencję, że nazwa pola jest taka sama, jak własności, ale poprzedzona podkreślnikiem). Modyfikacja każdej ze zdefiniowanych w powyższym listingu własności powoduje wywołanie metody Refresh, co prowadzi do odmalowania komponentu funkcją ColorProgressBar_Paint. Nie należy tej ostatniej metody wywoływać samodzielnie - jest ona asynchronicznie wywoływana przez metodę Refresh, co pozwala platformie .NET na optymalizowanie dzia-łania aplikacji.


Zobacz również