Dziś będzie o kontrolce Grid. Najbardziej zaawansowanej i dającej największe możliwości konfiguracyjne spośród wszystkich dostępnych standardowo paneli. Zaczynamy.

Najprostszy Grid uzyskamy po prostu deklarując

<Grid>

 

Grid>

Jednak w takim przypadku efekt nie będzie oszołamiający. Wszystkie dodawane kontrolki będą układane jedna na drugiej. Aby zmienić to zachowanie musimy zdefiniować wiersze i/lub kolumny.

RowDefinitions & ColumnDefinition

Wspomniane wiersze i kolumny, definiujemy w obrębie powyższych tagów. Oczywiście można zdefiniować różne ich ilości w zależności od potrzeb

<Grid.RowDefinitions>

    <RowDefinition />

    <RowDefinition />

    <RowDefinition />

Grid.RowDefinitions>

<Grid.ColumnDefinitions>

    <ColumnDefinition />

    <ColumnDefinition />           

Grid.ColumnDefinitions>

Powyższy kod, jak można się domyślać, tworzy 3 wiersze i 2 kolumny. Domyślnie są one o takim samym rozmiarze. Później pokażemy sobie jak możemy je różnicować. Teraz powiemy sobie jak możemy umieszczać elementy w poszczególnych komórkach

Attached properties

Grid udostępnia kilka attached properties (“doczepiane właściwości”??). Za pomocą Grid.Row oraz Grid.Column możemy zdefiniować wiersz i kolumnę, która będzie zajmowana przez naszą kontrolkę.

<Image Grid.Column=”0″ Grid.Row=”1″ Source=”clouds_Xsmall.jpg” />

I nasz obrazek znajdzie się w wierszu nr 2 (numerowanie od 0) i w 1. kolumnie.

Jeśli chcemy, aby kontrolka zajmowała więcej niż jedną komórkę wystarczy użyć Grid.ColumnSpan i/lub Grid.RowSpan i nasza kontrolka będzie zajmowac np. dwie kolumny.

Rozmiary

Domyślnie wiersze i kolumny, przyjmują taki rozmiar, aby zagospodarować całą przestrzeń jednakowo. oczywiście takie zachowanie często nie jest pożądane. Jak zatem możemy zmienić szerokość lub wysokość?

Pierwszym ze sposób, jest użycie trybu Auto. Jeśli ustawimy wysokość wiersza ustawimy na taką wartość to dopasuje się on do wysokości kontrolki, którą w sobie zawiera. Podobnie będzie z kolumną, ale w tym przypadku, możemy tylko dopasować szerokość (co jest w sumie oczywiste). Przykład.

<Grid.RowDefinitions>

    <RowDefinition />

    <RowDefinition Height=”Auto”/>

    <RowDefinition />

Grid.RowDefinitions>

Porównajcie z poprzednim przykładem

Inny sposobem, na ustalenie rozmiaru jest podanie wartości explicite.

<RowDefinition Height=”40″/>

Trzecią możliwością jest użycie notacji ‘gwiazdkowej’. O co chodzi?

Gwiazdki

Jako rozmiar (Height, Width) można wpisać gwiazdkę (*) lub jej wielokrotność (np. 4*). Jak to zadziała? Przyjmijmy, że mamy:

<Grid.RowDefinitions>

    <RowDefinition Height=”2*”/>

    <RowDefinition Height=”40″/>

    <RowDefinition Height=”3*”/>

Grid.RowDefinitions>

Środkowy wiersz, jako że ma wielkość ustawioną explicite na piksele, będzie miał taką właśnie wysokość. Pozostała część zostanie wzięta pod uwagę i podzielona na 5 części (3* + 2*). Dwie części zostaną przydzielone na pierwszy wiersz. Pozostałe 3 na ostatni. Chyba wszystko jasne? Jeszcze jak to zrobić z kodu:

GridLength lengthPixels = new GridLength(100); //explicite

GridLength lengthAuto = new GridLength(0, GridUnitType.Auto); //Auto

GridLength lengthStar = new GridLength(2, GridUnitType.Star); //Gwiazdka

Splitter’y

Grid umożliwia jeszcze ustalanie rozmiarów ręcznie w runtime. Służy do tego element GridSplitter. Wystarczy go umieścić w XAMLu i określić którego wiersza czy kolumny dotyczy. Jednak należy pamiętać, że musi on mieć swoją definicję wiersza lub kolumny, w której będzie osadzony. Trochę to uciążliwe.

<GridSplitter Grid.Row=”2″ Grid.ColumnSpan=”2″ HorizontalAlignment=”Stretch”/>

I na koniec omawiania splitterów jeszcze jedna właściwość. Umożliwiają one tworzenie grup, które będą współdzielić rozmiar. Myślę, że przykład najlepiej to wyjaśni. Definicja wierszy:

<Grid.RowDefinitions>

    <RowDefinition Height=”20″ />

    <RowDefinition Height=”3″/>

    <RowDefinition />           

    <RowDefinition />

Grid.RowDefinitions>

Dodajmy teraz do pierwszego i ostatniego wiersza właściwość

SharedSizeGroup=”myGroupd”

oraz na samej kontrolce grid

Grid.IsSharedSizeScope=”True”

Teraz jeśli będziemy mieli splittera, który będzie kontrolował rozmiar pierwszego wiersza, ostatni wiersz będzie automatycznie zmieniany, aby jego rozmiar dopasowywał się do tego pierwszego. Filmik?

Ciekawostki

Jeśli chcesz w run-time widzieć linie podziału na wiersze i kolumny ustaw ShowGridLines na True

Przy pisaniu tego posta zauważyłem ciekawą właściwość VS 2008. Wydawało mi si, że Desginer nie działa dla WPF a ja mogłem sobie w grid’a wrzucać kontrolki i ustawiać za pomocą myszki wielkość kolumn i wierszy. Czy to jakiś plugin czy coś przegapiłem?

Tyle na dziś. Następnym razem o Integrate Windows Forms controls into a WPF application