Witaj na Zine.net online Zaloguj się | Rejestracja | Pomoc

WPF to Go część 1

Minął długi czas odkąd cokolwiek pisałem na tym blogu. Nowy rok sprzyja postanowieniom, więc czas wcielić w życie pomysł, który kołatał mi się od dłuższego czasu po głowie.

Szukając odskoczni od codziennej pracy z aplikacjami webowymi, postanowiłem poduczyć się trochę programowania aplikacji desktopowych za pomocą książki Charles’a Petzolda „Application = Code + Markup” (którą polecam). Zapraszam zatem do cyklu (mam nadzieję, że w miarę regularnego) artykułów o moich początkach z WPF.

 WPF – tak w zasadzie to po co?

Windows Presentation Foundation  weszło w .NET 3.0 (trochę więcej o wpf na np.: http://msdn2.microsoft.com/en-us/library/aa663364.aspx). Po co było wprowadzać coś nowego, jeżeli Windows Forms działały i miały się dobrze? XAML pozwala na odseparowanie designu aplikacji, od jego zachowania i programistycznych „bebechów”. Zdecydowany plus…, ale XAML mógł być równie dobrze dodany do Windows Forms. Po co więc nowe kontrolki, namespace’y, itd.? MS doszedł do wniosku (moim zdaniem słusznego), że to co było wcześniej jest niewystarczające dla tworzenia atrakcyjnie wyglądających (czy wręcz „fajerwerkowych”) aplikacji windowsowych. Oczywiście takie programy da się tworzyć bez WPF, ale nakład pracy w celu uzyskania takich samych efektów byłby naprawdę duży. WPF ma służyć głównie tworzeniu świetnie wyglądających aplikacji i ma w tym zadaniu pomagać programistom najlepiej jak można.

Programowanie aplikacji tak, aby wyglądały dobrze u większości użytkowników wcale nie jest takie proste. Jeszcze kilka lat temu rozdzielczości ekranów spotykane u użytkowników były co najwyżej 2, 3 różne. Teraz mamy monitory do 20-kilku cali, panoramiczne, nie panoramiczne, laptopy duże, małe. Ta sama aplikacja może wyglądać całkowicie inaczej na dwóch różnych komputerach. Taka mała powtórka z rozrywki z tworzenia stron internetowych. Developerzy webowi mają do dyspozycji cssy, em-y, divy, itp., itd. i dają sobie radę tymi narzędziami. A co mamy dla windowsów?

Jeżeli nie piksele to co?

Jak zaczynać to oczywiście od aplikacji Hello World :) Na jakiś czas nie będę sięgał do xaml’a i designera z Visual Studio czy Expression Blend’a. Pierwszy powód to taki, że uważam, iż warto wiedzieć, jak poradzić sobie bez xaml’a - czysto programistycznie i bez designerów (albo przynajmniej rozumieć, co nam maszyna wygenerowała). Drugi powód jest prosty… jestem jeszcze za „zielony” :) i po prostu uczę się w takiej kolejności jak w książce (najpierw „Code” potem „Markup”).

Chciałem wyświetlić okno z tytułem Hello World, powiedzmy o wielkości 288x192, na środku ekranu. Taki kod:

this.Title = "Hello world!";

 

this.Width = 320;

this.Height = 240;

 

this.Top = (SystemParameters.WorkArea.Height - this.Height) / 2

        + SystemParameters.WorkArea.Top;

this.Left = (SystemParameters.WorkArea.Width - this.Width) / 2

        + SystemParameters.WorkArea.Left;

 

Jeden rzut oka na intellisense w VS i widać że coś jest nie tak. Width i Height są podawane jako double a nie jako int. Odpowiedź jest prosta. Większość rozmiarów w WPF nie jest podawana w pikselach. Wysokość i szerokość podawana jest w niezależnych jednostkach. Jedna taka jednostka jest równa 1/96 cala (stąd podane przeze mnie rozmiary okna 288x192 to tak naprawdę 3 cale na 2 cale). Jeżeli w Windowsie jest ustawione skalowanie DPI na 96, wówczas podane wymiary będą równały się ilościom pikseli na ekranie. Podejście takie pozwala na uniezależnienie się od tego na jakim ekranie (czy urządzeniu) będzie wyświetlana aplikacja. Wbrew pozorom to już jest „problemem”. Dario  może potwierdzić. Dostał laptopa o rozdzielczości „Full HD” i nic na nim nie widział :) Zwiększenie DPI pomogło, ale niektóre aplikacje po prostu się „rozjechały”.

Jeszcze jedno wyjaśnienie do kodu: aby wycentrować okno aplikacji użyłem użyłem SystemParameters.WorkArea, które zwraca prostokąt odpowiadający dostępnemu obszarowi dla aplikacji (ekran minus wszystkie taskbary, sidebary itp.).

Kolory

Takich nowośći w WPF jest więcej. Kolejna to – kolory. Przyzwyczajeni jesteśmy do podawania kolorów w skali RGB, czyli każdy ze składników w skali od 0 do 255. W WPF jest jeszcze możliwość podawania składowych czerwonego, zielonego i niebieskiego w liczbach rzeczywistych. Ta skala nazywa się scRGB – 0 scRGB odpowiada 0 w RGB, a 1 scRGB – 255 RGB. To co mi się podoba to bardziej naturalne (przynajmniej dla mnie) odwzorowanie skali kolorów tzn: 0.5-0.5-0.5 w skali scRGB jest subiektywnie w połowie między białym a czarnym – natomiast 127-127-127 RGB już nie bardzo :) scRGB ma lepiej odwzorowywać nieliniowość (trudne słowo) percepcji (jeszcze trudniejsze słowo) jasności i kolorów. Lepiej zobrazuje to pewnie poniższa tabela z książki Charles’a Petzolda:

scR/G/B

R/G/B

<= 0

0

0.1

89

0.2

124

0.3

149

0.4

170

0.5

188

0.6

203

0.7

218

0.8

231

0.9

243

>= 1.0

255

Jak łatwo zauważyć w pierwszym i ostatnim wierszu są znaki większości i mniejszości. Jak się okazuje można podawać poszczególne składowe jako liczby ujemne i większe od 1 (w końcu mogą to być liczby rzeczywiste). Takie podejście ma umożliwić zdefiniowanie kolorów na inne urządzenia niż monitory, urządzenia które mogą wyświetlać więcej kolorów niż monitory. Trochę trudno mi to sobie wyobrazić, ale możliwość jest.

W ramach zabawy WPF’em i przeglądania przykładów z książki zmodyfikowałem jeden z podanych tam programów. Tło aplikacji miało się zmieniać w zależności od położenia kursora względem środka okna. Poszczególne składowe koloru w skali scRGB.

Pominę fragment z obliczaniem odległości kursora od środka ekranu – matematykę miałem dawno ;) Najważniejsze linie kodu to.

1.       Ustawienia jako tła aplikacji SolidColorBrush

brush = new SolidColorBrush(Colors.White);

this.Background = brush;

2.       Zamiana właściwości Color tła oraz podmiana tytułu na pasku aplikacji

float scrgb = (float)(vectMouse.Length / ellipse.Length);

brush.Color = Color.FromScRgb(1, scrgb, scrgb, scrgb);

 

this.Title = String.Format("scRGB: {0:F}", scrgb);

Metoda FromScRGB jako pierwszy parametr przyjmuje wartość kanału Alpha czyli przezroczystości. Pełny kod tej małej aplikacji do ściągnięcia poniżej.

Najpiękniejsze jest to że po zamianie właściwości Color nic już nie muszę robić. Żadnego odświeżania czy odmalowywania okna – wszystko dzieje się „automagicznie” i wraz z poruszaniem myszką zmienia się szarość tła okna.  Dzieje się tak dzięki eventowi Changed, o którym pewnie kiedyś napiszę więcej.  W pasku tytułu okna pojawia się wyliczona wartość scRGB – zobaczcie, że po wejściu w jeden z rogów pojawi się liczba > 1. Niestety tło aplikacji bielsze już nie będzie :) (nawet jak potraktujemy je wiodącym proszkiem do prania ;) ).

To by było na tyle tym razem.  Dla ciekawskich dorzucam jeszcze kod innej aplikacji, gdzie jako tło jest RadialBrush, a środek gradientu porusza się za myszką.

Źródła (razem z exe'kami):

1.       Prosta aplikacja HelloWorld – [źródła]

2.       Tło aplikacji zmienia odcień pomiędzy kolorami białym i czarnym w zależności od położenia myszy – [źródła]

3.       Okrągły gradient w tle  porusza się za kursorem myszy – [źródła]

 

Opublikowane 16 stycznia 2008 22:10 przez yoshi
Filed under:

Komentarze:

# re: WPF to Go część 1

10 lutego 2009 22:55 by 0x11

fajne :)

Komentarze anonimowe wyłączone