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
Founder of Octal Solutions a .NET software house.
Passionate dev, blogger, occasionally speaker, one of the leaders of Wroc.NET user group. Microsoft MVP. Podcaster – Ostrapila.pl