02. Wprowadzenie do Silverlight 5.0 i XAML oraz środowiska narzędziowego cz. 2

02. Wprowadzenie do Silverlight 5.0 i XAML oraz środowiska narzędziowego cz. 2

Autor: Paweł Kruczkowski

Opublikowano: 11/6/2011, 12:00 AM

Liczba odsłon: 13284

Język XAML (ang. Extensible Application Markup Language) jest językiem znaczników i preferowanym do tworzenia interfejsów Silverlight, które są zapisywane w plikach o rozszerzeniu .xaml. Pomimo faktu, że interfejs ten jest oprogramowywany przez język obiektowy np. C#, to trzeba mieć świadomość obiektowości XAML. Tak naprawdę każdy element tego języka jest obiektem.

W HTML4 nagłówek z reguły opisywaliśmy jako:

Powyższa linijka to prosty przykład wyświetlenia tekstu: Witaj srebrne światełko (o rozmiarze czcionki 25) za pomocą kontrolki TextBlock. To samo jednak można osiągnąć w code-behind pliku .xaml czyli .xaml.cs:

TextBlock textBlock = new TextBlock();
textBlock.FontSize = 25;
textBlock.Text = " Witaj srebrne światełko";

XAML jest językiem znaczników, który bazuje na innym znacznikowym języku – XML. To oznacza, że plik .xaml złożony jest ze znaczników, a dokładniej: z tagów. W tagach znajdują się różne słowa kluczowe, które mogą oznaczać klasy, właściwości czy zdarzenia, zaś zadaniem kompilatora XAML-a jest przepisanie ich do CLR (ang. Common Language Runtime). W XAML-u zgodnie z zasadą XML, każdy tag rozpoczynający musi mieć także tag zamykający (tzw. zapis rozszerzony):

Istnieje jednak drugi sposób zapisu powyższej linijki, w którym nie używamy taga zamykającego (tzw. zapis skrócony):

Listing 1. Siatka Grid z polem tekstowym TextBox. Powyższy kod pochodzi z solucji 2_1_SL.sln (do ściągnięcia z załączników niniejszego artykułu)

Wynikiem powyższego przykładu będzie:

Zgodnie ze specyfikacją XML, na podstawie którego powstał XAML, poprawny dokument może mieć tylko jeden element główny – korzeń dokumentu (czyli tzw. root element).

Głównym elementem pliku MainPage.xaml (plik z solucji 2_1_SL.sln ) jest UserControl – klasa, dzięki której programista może tworzyć obiekt pod tytułem: kontrolka użytkownika. Co więcej, UserControl jest specyficzną klasą, po której mogą dziedziczyć kontrolki tworzone przez użytkownika. Pisanie aplikacji w Silverlight jest zawsze tworzeniem nowej kontrolki (każdy kolejny plik .xaml będzie rozpoczynał się od znacznika UserControl).

Wewnątrz kontroli UserControl może znaleźć się maksymalnie JEDEN element – zwykle jest to kontener. W naszym przykładzie (2_1_SL) tym kontenerem jest siatka Grid.

UWAGA: popularnymi kontenerami używanymi w SL są: Canvas, StackPanel oraz Grid. Kanwa (ang. Canvas) charakteryzuje się pozycjonowaniem absolutnym – podajemy dokładną pozycję obiektu, który pozycjonujemy, podczas gdy panel stosu (ang. Stack Panel) oraz siatka (ang. Grid) umożliwiają pozycjonowanie relatywne.

Korzeń UserControl posiada m.in. właściwości: DesignWidth oraz DesignHeight. Określają one odpowiednio szerokość i wysokość kontrolki, czyli tak naprawdę pisanej przez nas aplikacji. Można tutaj podać dowolne liczby lub usunąć obie właściwości (w takiej sytuacji, gdy usuniesz DesignWidth oraz DesignHeight, sprawisz, że nasz aplikacja będzie zajmowała całą dostępną powierzchnię w przeglądarce i będzie się dostosowywała do wielkości przeglądarki.

Na listingu 1 możesz znaleźć atrybut xmlns. Definiuje on domyślną przestrzeń nazw (ang. Namespace) aplikacji SL. W domyślnej przestrzeni nazw zawarte są definicje obiektów, których można użyć w aplikacji, czyli np. Grid, TextBlock czy Run. Gdybyśmy usunęli xmlns z kodu, wówczas kompilator nie rozpoznałby tych elementów i zwróciłby błąd.

Jako wartość domyślnej przestrzeni nazw podaje się hiperłącze do mapowanej przestrzeni nazw, czyli:

 

Listing 2. Domyślna przestrzeń nazw w XAML-u

Obok domyślnej przestrzeni nazw, istniej możliwość zdefiniowania dodatkowych przestrzeni nazw. Definicje tych przestrzeni muszą znaleźć się w korzeniu UserControl i muszą być opatrzone odpowiednim prefiksem.

Listing 3. Przykłady dodatkowych przestrzeni nazw, które są standardowo generowane przez Visual Studio podczas tworzenia projektu

Dodatkowe przestrzenie nazw są bardzo ważne w SL. Dzięki nim możemy korzystać z mechanizmu zdarzeń oraz dołączać własne, wcześniej napisane kontrolki do swojej aplikacji SL.

Obok zdefiniowania przestrzeni, bardzo ważnym krokiem będzie skorzystanie z niej. W tym celu, aby użyć obiektów zdefiniowanych w dodatkowej przestrzeni nazw, należy zastosować następującą składnię:

Dokonajmy modyfikacji kodu z listingu 1 dodając prefiks: „mojPrefiks” do domyślnej przestrzeni nazw (w tym momencie nie będzie żadnej przestrzeni domyślnej):

Listing 4. Dodanie prefiksu mojPrefiks do domyślnej przestrzeni xmlns

Jak prezentuje powyższy listing, nasza aplikacja zgłasza błędy. Aby się w ogóle skompilowała, musimy koniecznie dodać prefiks mojPrefiks do wszystkich elementów, które korzystają z przestrzeni domyślnej, tj. Grid, TextBlock, Run, LineBreak.

UWAGA: prefiks mojPrefiks musi się pojawić nawet w samym znaczniku UserControl, w którym są definiowane przestrzenie nazw. To oznacza, że UserControl również korzysta z domyślnej przestrzeni nazw.

Listing 5. Poprawna wersja projektu 2_1_SL z prefiksem mojPrefiks

Dodatkowa przestrzeń nazw „x”

Przestrzeń nazw z prefiksem x jest bardzo ważną przestrzenią nazw, ze względu na klasy jakie mapuje. Przestrzeń ta musi znaleźć się w pliku .xaml jeśli w aplikacji SL używamy zdarzeń czy szablonów kontrolek.

Przestrzeń zawiera definicje kilku ważnych konstrukcji m.in.:

  1. x:Class – definiuje przestrzeń nazw i klasę, która dostarcza code-behind dla danego pliku .xml
  2. x:Name – ustala unikalną nazwę obiektu w ramach .xaml, po której będzie można rozpoznać dany obiekt w pliku code-behind (innymi słowy: identyfikuje obiekt nadając identyfikator jak ID kontrolki w ASP.NET)
  3. x:Key – ustala unikalny klucz w katalogu zasobów

Domyślna własność znacznika

W języku XAML jedne elementy mogą znajdować się wewnątrz innych obiektów. Listing 1 przedstawia kontener Grid, w którym znajduje się kontrolka TextBlock. W obiekcie TextBlock znajdują się w odpowiedniej kolejności kontrolki Run (do wyprowadzania tekstu) oraz LineBreak (oznacza koniec linii). W ten sposób powstaje hierarchiczna struktura zależności (tzw. drzewo zależności).

Bardzo ciekawą właściwością w języku znaczników XAML jest tzw. własność domyślna. Jest to cecha, dzięki której w niektórych przypadkach nie musisz w kodzie pisać nazwy właściwości.

Listing 6. Domyślna własność obiektu Run to Text

Listing 6 wyprowadza na stronie SL tekst: „Bold Text” dzięki własności domyślnej kontrolki Run – Text. Dla przykładu Button (przycisk) posiada własność domyślną Content zaś TextBlock – Text. Natomiast dla wszystkich kontenerów domyślną własnością jest Children (co oznacza zdolność przechowywania kolekcji obiektów).

Składnia atrybutowa oraz elementów właściwości

W języku XAML istnieją 2 sposoby deklarowania właściwości:

  1. składnia atrybutowa
  2. Polega na tym, że wszystkie właściwości obiektu są określane w postaci jego atrybutów.

Listing 7. Składnia atrybutowa

    Obiekt Run ma zadeklarowane w postaci atrybutów następujące właściwości:

    1. FontFamily – określa rodzaj czcionki,
    2. FontStyle – określa styl czcionki,
    3. FontSize – określa wielkość czcionki.
  1. składnia elementów właściwości
  2. Podstawową różnicą w stosunku do składni atrybutowej jest to, że należy stosować rozszerzony zapis, używając zarówno taga otwierającego jak i zamykającego. Pomiędzy tymi tagami należy podać definicje właściwości.

Listing 8. Przedstawia definicję 2-óch kolumn siatki Grid za pomocą składni elementów właściwości

Ćwiczenie

Otwórz projekt 2_2_SL i zapoznaj się z XAML-em zawartym w projekcie.

Zauważ, że został wstawiony kontener Grid, który tworzy na stronie tabelę składającą się z 3-ech wierszy i kolumn o odpowiedniej szerokości i wysokości. Każda komórka tabeli (stworzonej przez siatkę Grid) ponumerowana jest w postaci x,y – gdzie x oznacza numer wiersza, zaś y – numer kolumny. Pierwsza komórka więc opatrzona jest wartością 0,0 (pierwsza komórka w lewym górnym rogu), zaś ostatnia – 2,2. Zauważ, że do ostatniej komórki tabeli (przyp. 2,2) został wstawiony obiekt Prostokąt (ang. Rectangle) wypełniony kolorem żółtym. Prostokąt wypełniony kolorem czerwonym znajduje się na przecięciu komórki 0,0 jak i 1,0 (za taki stan rzeczy odpowiada właściwość RowSpan).

A za co odpowiada właściwość ColumnSpan?

Listing 9. Projekt 2_2_SL

Listing 9. Wynik działania 2_2_SL

Podsumowanie

Niniejszy artykuł wprowadza nas w świat języka XAML, dzięki któremu tworzymy rozwiązania Silverlight. Poznaliśmy pojęcia obiektu, właściwości (jej składni atrybutowej oraz elementowej) oraz domyślnej i dodatkowej przestrzeni nazw. W kolejnym artykule będziemy dalej zagłębiać się w język znaczników XAML rozwiązań SL.