Přejít k navigační liště

Zdroják » Různé » Nástroje pro tvorbu layoutu v Silverlightu 2.0 a Silverlight toolkitu

Nástroje pro tvorbu layoutu v Silverlightu 2.0 a Silverlight toolkitu

Články Různé

V tomto díle se vrátíme k úplným základům Silverlightu. Ukážeme si čtyři nástroje sloužící k tvorbě layoutu, které má Silverlight 2.0 integrované a tento výběr následně rozšíříme o další dva nástroje, které přináší Silverlight toolkit. Plus jeden šikovný nástroj nakonec.

Úplně první věcí, kterou musíte udělat, při tvorbě uživatelského rozhraní, je vytvořit si kostru stránky – neboli layout. Toto pravidlo platí pro tvorbu uživatelského rozhraní ve všech jazycích popisujících GUI. Většinou platí, že změna layoutu vám zabere trojnásobek času, nežli jeho samotná tvorba. Proto je dobré si celý layout na začátku důkladně promyslet.

Silverlight 2.0 má integrované následující komponenty:

  • Canvas – kontejner s možností definování pozic svých „potomků“
  • StackPanel – kontejner umožňující řazení prvků horizontálně či vertikálně za sebou
  • Grid – tabulka
  • ScrollViewer – kontejner umožňující zobrazení posuvníků

S těmito nástroji si v drtivé většině vašich aplikací vystačíte. Proč si ale nezjednodušit život, když to jde pomocí komponent Silverlight toolkitu. Konkrétně těchto dvou:

  • DockPanel – umožňuje orientování potomků různými směry
  • WrapPanel – zajišťuje zalamování potomků do řádků či sloupců

Ještě bych rád na konec uvedl komponentu TabControl . Zde by mohl někdo namítnout, že se nejedná o komponentu sloužící pro tvorbu layoutu. A měl by částečně i pravdu (jelikož se jedná o komponentu funkční). Nicméně z pohledu vývojáře či designera GUI je jednou z variant, se kterou musí počítat již při tvorbě layoutu.

Canvas

Canvas je nejoblíbenějším a nejsvobodnějším nástrojem pro tvorbu layoutu. Čím to? Jeho hlavní funkcionalita spočívá v tom, že umožňuje potomkům (tedy všem komponentám, které jsou v Canvasu  obsaženy) definování pozice uvnitř Canvasu. To z něj dělá jednoduchý, ale zároveň mocný nástroj pro tvorbu 2D grafiky.

Pojďme si ukázat velice jednoduchý příklad. Nakreslíme si smajlíka (který se moc nesměje). V kódu si všimněte třech hlavních prvků definujících prvek v Canvasu  – Top, Left, ZIndex. První dva určují pozici a poslední úroveň (tzn. prvky s vyšším číslem budou překrývat prvky s nižším číslem).

<Canvas Width="200" Height="200">
  <Ellipse Fill="Yellow"
           Width="180"
           Height="180"
           Canvas.Left="10"
           Canvas.Top="10"
           Canvas.ZIndex="0"/>
  <Ellipse Fill="Black"
           Width="10"
           Height="30"
           Canvas.Top="60"
           Canvas.Left="65"
           Canvas.ZIndex="1"/>
  <Ellipse Fill="Black"
           Width="10"
           Height="30"
           Canvas.Top="60"
           Canvas.Left="125"
           Canvas.ZIndex="1"/>
  <Line Stroke="Black"
        X1="0"
        X2="100"
        Y1="0"
        Y2="0"
        Canvas.Left="50"
        Canvas.Top="140"
        Canvas.ZIndex="1"/>
</Canvas> 

Výsledek:

Ukázka použití Canvasu

StackPanel

Jedná se také o velice jednoduchý a velmi často používaný prvek (vždyť v jednoduchosti je krása). StackPanel využijeme hlavně tehdy, pokud budeme chtít prvky uspořádat horizontálně či vertikálně. Pojďme si StackPanel ukázat v akci.

<StackPanel Orientation="Vertical" Width="100" Height="100" Background="Coral">
  <Rectangle Fill="Black"
             Width="20"
             Height="20"
             HorizontalAlignment="Center"/>
  <Rectangle Fill="Black"
             Width="20"
             Height="20"
             HorizontalAlignment="Left"/>
  <Rectangle Fill="Black"
             Width="20"
             Height="20"
             HorizontalAlignment="Right"/>
  <Rectangle Fill="Black"
             Width="20"
             Height="20"
             HorizontalAlignment="Center"/>
  <Rectangle Fill="Black"
             Width="20"
             Height="20"
             HorizontalAlignment="Right"/>
</StackPanel> 

Výsledek:

Ukázka využití komponenty StackPanel

Zde je vidět, jak se nám prvky skládají pod sebe a podle hodnoty atributu HorizontalAlignment jsou zarovnány vlevo, vpravo nebo na střed.

Grid – tabulka

V minulých letech se stalo používání tabulky pro rozvržení stránky velice nepopulární. Za tento fakt mohlo z velké části HTML, kde opravdu rozvržení stránky pomocí tabulky nebývá šťastným řešením. Naopak u XAMLu je tento způsob rozvržení stránky jedním z nejčastějších.

Práce s tabulkou probíhá tak, že si nejdříve definujeme sloupce a řádky. Následně potomky adresně umísťujeme do vytvořených políček. Na následujícím příkladu si ukážeme, jak vytvořit formulář pro přihlášení.

<Grid ShowGridLines="True" Width="350" Height="250" Background="LightGray">

    <!--definice sloupcu-->
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="200"/>
    </Grid.ColumnDefinitions>

    <!--definice radku-->
    <Grid.RowDefinitions>
        <RowDefinition Height="30"/>
        <RowDefinition Height="30"/>
        <RowDefinition Height="30"/>
    </Grid.RowDefinitions>

    <!--komponenty v tabulce-->
    <TextBlock Text="Uživatelské jméno:"
               Grid.Column="0"
               Grid.Row="0"
               HorizontalAlignment="Right"
               VerticalAlignment="Center"
               Margin="2"/>

    <TextBox Grid.Column="1"
             Grid.Row="0"
             Margin="2"/>

    <TextBlock Text="Heslo:"
               Grid.Column="0"
               Grid.Row="1"
               HorizontalAlignment="Right"
               VerticalAlignment="Center"
               Margin="2"/>

    <TextBox Grid.Column="1"
             Grid.Row="1"
             Margin="2"/>

    <Button Content="Přihlásit"
            Grid.Column="1"
            Grid.Row="2"
            Margin="2"/>

</Grid> 

Výsledek (linky tabulky jsou vidět jen tehdy, pokud máme nastaveno ShowGridLines na True  – zde jsou jen pro ukázku):

Ukázka přihlašovacího formuláře

Pokud budeme chtít, aby nějaké komponenty zasahovaly do více polí, použijeme k tomu Grid.RowSpan a Grid.ColumnSpan, kde definujeme, kolik řádků či sloupců komponenta zabere.

ScrollViewer

Kontejner ScrollViewer používáme hlavně v případech, kdy víme, že dané pole bude mít více obsahu nežli mu dovolí jeho výška či šířka. ScrollViewer nám dovoluje si nastavit jejich zobrazování – zobrazeno neustále, automatické zobrazení nebo vypnuto.

<ScrollViewer Width="200" Height="200"
              VerticalScrollBarVisibility="Visible"
              HorizontalScrollBarVisibility="Disabled">

  <!--text ci komponenty-->

</ScrollViewer> 

Výsledek:

Ukázka ScrollVieweru

Komponenty Silverlight toolkitu

Ještě před tím než začneme používat komponenty Silverlight toolkitu, musíme přiřadit knihovnu obsahující komponenty do našeho projektu. Podrobný popis naleznete v předchozím článku.

DockPanel

Funkcionalita DockPanelu spočívá v možnosti přiřazovat komponenty k různým stranám DockPanelu  – doprava, doleva, nahoru, dolu. Působí tedy jako mnohosměrný StackPanel. Velkou výhodou ale je, že tyto komponenty spolu v DockPanelu  umí koexistovat a nepřekrývají se (jak vidíme na ukázce).

<Controls:DockPanel Height="200" Width="300" Background="LightGray" LastChildFill="True">
  <Rectangle Fill="Blue" Controls:DockPanel.Dock="Top" Height="30"/>
  <Rectangle Fill="Blue" Controls:DockPanel.Dock="Bottom" Height="30"/>
  <Rectangle Fill="Black" Controls:DockPanel.Dock="Left" Width="30"/>
  <Rectangle Fill="Red" Controls:DockPanel.Dock="Right" Width="30"/>
  <Rectangle Fill="Green"/>
</Controls:DockPanel> 

Vidíme zde 5 obdélníků. Každý je přiřazen k jedné straně a podle toho, jak vysoko jsou v kódu postaveni, taková je i jejich priorita vykreslení. LastChildFill je nastaveno na True, jelikož chceme, aby poslední obdélník vyplnil všechen zbývající prostor.

Ukázka řazení komponent v DockPanelu

Pojďme si náš příklad trochu rozvinout a namísto horního a levého obdélníku si dát menu. Poslední využijeme například k vypsání obsahu.

<Controls:DockPanel Height="200" Width="300" Background="LightGray" LastChildFill="True">

    <!--menu 1-->
    <StackPanel Background="Blue"
                Orientation="Horizontal"
                Height="Auto"
                Controls:DockPanel.Dock="Top">

        <Button Content="#1" Width="55" Margin="2"/>
        <Button Content="#2" Width="55" Margin="2"/>
        <Button Content="#3" Width="55" Margin="2"/>
        <Button Content="#4" Width="55" Margin="2"/>
        <Button Content="#5" Width="55" Margin="2"/>

    </StackPanel>

    <!--zapati-->
    <Rectangle Fill="Blue" Controls:DockPanel.Dock="Bottom" Height="30"/>

    <!--menu 2-->
    <StackPanel Background="Yellow"
                Orientation="Vertical"
                Height="Auto"
                Controls:DockPanel.Dock="Left">

        <Button Content="#01" Margin="2"/>
        <Button Content="#02" Margin="2"/>
        <Button Content="#03" Margin="2"/>
        <Button Content="#04" Margin="2"/>
        <Button Content="#05" Margin="2"/>

    </StackPanel>

    <!--pravy pruh-->
    <Rectangle Fill="Red" Controls:DockPanel.Dock="Right" Width="30"/>

    <!--obsah-->
    <ScrollViewer VerticalScrollBarVisibility="Visible"
                  HorizontalScrollBarVisibility="Disabled">

        <TextBlock Text="..."
                   TextWrapping="Wrap"/>

    </ScrollViewer>

</Controls:DockPanel> 

Výsledek:

Ukázka rozvržení stránky pomocí DockPanelu

WrapPanel

Tato komponenta také částečně vychází ze StackPanelu. Pokud skládáte prvky ve WrapPanelu za sebe a dojdete na konec panelu, následující komponenta bude již v dalším řádku či sloupci. Tato komponenta nalezne excelentní využití například při tvorbě fotogalerie či jakékoliv jiné galerie (ukázka jednoduché fotogalerie). Na příkladu si ukážeme, jak se prvky skládají do WrapPanelu, pokud budeme hýbat s šířkou panelu. Nejprve si připravíme kód:

<Controls:WrapPanel Background="LightGray"
                    Orientation="Horizontal"
                    Height="250"
                    Width="120">

    <Rectangle Fill="Black" Height="30" Width="60"/>
    <Rectangle Fill="White" Height="10" Width="40"/>
    <Rectangle Fill="Black" Height="20" Width="50"/>
    <Rectangle Fill="White" Height="40" Width="40"/>
    <Rectangle Fill="Black" Height="20" Width="30"/>
    <Rectangle Fill="White" Height="10" Width="90"/>
    <Rectangle Fill="Black" Height="40" Width="20"/>
    <Rectangle Fill="White" Height="10" Width="90"/>
    <Rectangle Fill="Black" Height="20" Width="120"/>
    <Rectangle Fill="White" Height="40" Width="40"/>
    <Rectangle Fill="Black" Height="20" Width="30"/>
    <Rectangle Fill="White" Height="10" Width="90"/>
    <Rectangle Fill="Black" Height="40" Width="20"/>
    <Rectangle Fill="White" Height="10" Width="90"/>
    <Rectangle Fill="Black" Height="20" Width="120"/>

</Controls:WrapPanel> 

Výsledek:

Řazení prvků ve WrapPanelu při šířce 120px

Pokud změníme šířku WrapPanelu na 200 px dostaneme následující výsledek, kde vidíme, že se obdélníky přeskládali do šířky WrapPanelu.

Řazení prvků ve WrapPanelu při šířce 200px

A nakonec rozšíříme WrapPanel na 350 px.

Řazení prvků ve WrapPanelu při šířce 350px

TabControl

Tato komponenta slouží k separování určitých částí obsahu do různých tématických celků. Jedná se o komponentu, která nám může v mnoha případech pomoci zpřehlednit rozložení stránky. Namísto toho, abychom zobrazovali všechny informace vedle sebe nebo pod sebou, necháme uživatele, aby si zvolil sám, jakou informaci chce zobrazit. Tato komponenta je velice rozšířená především na desktopových platformách. Poslední dobou se ale čím dál tím častěji objevuje i na webu.

Proto, abychom mohly tuto komponentu použít, musíme zařadit do hlavičky jmenný prostor System.Window­s.Controls, ve kterém TabControl nalezneme. Pro jednoduchost můžeme také ve Visual Studiu přetáhnout TabControl z Toolboxu. Visual Studio za nás následně vykoná přiřazení jmenného prostoru.

Pojďme si nyní vytvořit pár tabulek. Budeme chtít, aby každá obsahovala jiný prvek.

<basics:TabControl>
    <basics:TabItem Header="Text">
        <TextBox Text="Jmenuji se jan a mám rád dobré jídlo"
                 FontSize="38"
                 TextWrapping="Wrap"/>
    </basics:TabItem>
    <basics:TabItem Header="Kolečko">
        <Ellipse Fill="Red"
                 Width="100"
                 Height="100"/>
    </basics:TabItem>
    <basics:TabItem Header="Obdélník">
        <Rectangle Fill="Peru"
                   Height="100"
                   Width="200"/>
    </basics:TabItem>
    <basics:TabItem Header="Kalendář">
        <basics:Calendar></basics:Calendar>
    </basics:TabItem>
</basics:TabControl> 

Všimněte si struktury TabControlu, nejdříve definujeme celý TabControl a následně do něj vkládáme jednotlivé položky. Výsledek bude vypadat nějak takto:

Ukázka použití TabControlu

Příklad si můžete vyzkoušet online.

Online ukázka a zdrojové kódy

Všechny probrané příklady si můžete vyzkoušet online.

K dispozici máte také zdrojový kód všech ukázek: Demo tvorby layoutu v Silverlightu (ZIP 2977051 bytů).

Závěrem

Stejně tak jako tomu je v jiných jazycích, tak i u XAMLu je nutné při návrhu GUI mít určitou disciplínu. Jsou určité věci, kterým by jste se při tvorbě GUI měli vyhnout. Tou hlavní a zásadní je přílišné vnořování různých komponent (jinak byste mohli brzy volat: já se v tom nevyznám, já se v tom neorientuju). Pokud tomuto nešvaru podlehnete, tak je to téměř jistá cesta do XAML pekel. Dříve či později se vám stane, že se ve svém kódu nevyznáte.

Bohužel v tuto chvíli neexistuje žádná spásná „bible“, která by nám napovídala jak psát XAML kód (nebo jsem na ní v dosavadním pátrání nenarazil – pokud někdo z vás ano, prosím odkažte na ní v komentářích), abychom se za čas z něho nepomátli. Ale všeobecným pravidlem je: použít pro layout stránky vždy jen jeden dominantní prvek a ostatní používat jen tehdy, pokud jsme si jisti, že jsou přínosem (ne zkázou).

Co nás čeká příště?

V příštím díle se vrhneme po stopách stylování komponent a šablonách.

Komentáře

Subscribe
Upozornit na
guest
3 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
tobik

Tak jsem článek spíš zběžně prolétával a oko mi padlo na ScrollViewer. Přijde mi to hrozně nesmyslné :-), mnohem elegantnější mi přijde způsob, jaký se používá v HTML a CSS (tedy jednoduchý <div>, čili odstavec textu, a css vlastnost overflow).

Jako další nesmysl mi přijde to, že vlastnost *ScrollBarVisibility používá pro zobrazení "visible" a pro skrytí "disabled". Mnohem logičtější by bylo "visible/hidden" či "enabled/disabled". Ten, kdo to navrhoval, musel mít zrovna slabší chvilku:D

tobik

Aha, tak jsem si špatně s tou vlasností *ScrollBarVisiblity špatně přečetl:) Samozřejmě to význam má.

Štěpán Bechynský

Do ScrollViewer můžete dát cokoliv, u čeho předpokládáte, že bude přesahovat rozměr vymezeného prostoru. Nejen ListBox.

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.