Design se styly a šablonami v Silverlightu 2.0

Nedávno jsme si ukázali, jaké komponenty můžete v Silverlightu používat. Dnes si předvedeme, jak tyto komponenty přeměňovat k obrazu svému. Nahlédneme pod pokličku stylování, tvorbě šablon a dokonce si ukážeme něco málo z animací.

Seriál: Praktické užití Silverlight 2.0 (12 dílů)

  1. Praktické užití Silverlight 2.0: Data Binding 15.12.2008
  2. Praktické užití Silverlight 2.0: DataGrid 22.12.2008
  3. Praktické užití Silverlight 2.0: UserControl 29.12.2008
  4. Co zajímavého přínáší Silverlight toolkit 5.1.2009
  5. Silverlight toolkit a vizualizace dat 12.1.2009
  6. Jak na komponenty AutoCompleteBox a TreeView ze Silverlight toolkitu 19.1.2009
  7. Nástroje pro tvorbu layoutu v Silverlightu 2.0 a Silverlight toolkitu 26.1.2009
  8. Design se styly a šablonami v Silverlightu 2.0 2.2.2009
  9. Základy 2D grafiky v Silverlightu 2.0 16.2.2009
  10. Dynamicky generované komponenty v Silverlightu 2.0 3.3.2009
  11. Úvod do streamování médií v Silverlightu 2.0 16.3.2009
  12. Práce s videem v Silverlightu 2.0 1.6.2009

Stejně tak jako nástroje pro tvorbu layoutu, o kterých jsem psal v minulém díle, tak i stylování patří do kategorie absolutních základů. Což vlastně znamená, že pokud chcete tvořit aplikace v Silverlightu, bez stylování se prostě neobejdete (je tomu tak i v jiných technologiích). Kdyby tento článek byl o HTML, tak by měl nadpis „Základy CSS“.

Co mám na mysli základním stylováním? Není to nic jiného, než práce s barvou či velikostí písma u  TextBlocku, změna barvy pozadí v Canvasu, orámování obdélníku apod.

Článek si pro přehlednost rozdělíme na 3 části. Nejprve si představíme základní principy stylování. V dalších dvou částech si na příkladu ukážeme, jak se vytvářejí šablony pro komponenty a základy animací.

Styly

Asi nebude třeba zabíhat do absolutních základů, jelikož principy stylování jsou ve většině jazyků podobné. U každé komponenty, kterou ve vaší aplikaci používáte, máte dvě možnosti, jak ji nastylovat.

  • První je definice všech vlastností přímo u každé komponenty.
  • Druhá možnost je, že si vlastnosti předdefinujete a pak je k dané komponentě přiřadíte.

Nás dnes bude primárně zajímat druhá varianta.

Pokud si v XAMLu chcete předdefinovat styly, použijeteResources (zdroje). Máte na výběr z dvou zdrojů.

  • Prvním zdrojem je zdroj stránky (to znamená, že si styly definujete přímo ve stránce, kde je budete používat).
  • Druhým zdrojem je zdroj celé aplikace (pokud si definujete styly zde, můžete je používat kdekoliv v celé aplikaci).

Principem se výrazně neliší od CSS.

Abychom jen nechodili kolem horké kaše, pojďme si to ukázat názorně. Vytvoříme si několik TextBlocků a nadefinujeme si u nich pár vlastností.

<TextBlock x:Name="mujTextBox"
           Text="Silverlight 2.0"
           FontFamily="Times New Roman"
           FontSize="48"
           FontWeight="Bold"
           Foreground="Orange"
           Margin="30"/>

<TextBlock x:Name="mujTextBox"
           Text="nemá ve znaku oranžovou"
           FontFamily="Times New Roman"
           FontSize="48"
           FontWeight="Bold"
           Foreground="LightBlue"
           Margin="30"/> 

Výsledkem je oranžovo-modrý nápis:

Oranžovo-modrý nápis

Příklad trochu zjednodušíme, pokud bychom pokračovali dál stejným způsobem, brzy by byl kód nepřehledný. Pojďme tedy přemístit styly do zdroje stránky.

Při předdefinování stylů musíme dodržet určitou formu. Nejprve si definujeme Style , jméno a komponentu, které se tento styl bude týkat. Následně si pomocíSetter nastavíme, jaká vlastnost se definuje a její hodnota. A to celé umístíme do  UserControl.Resources.

<UserControl.Resources>

     <Style x:Key="stylTextBlocku" TargetType="TextBlock">
         <Setter Property="FontFamily" Value="Times New Roman"/>
         <Setter Property="FontSize" Value="48"/>
         <Setter Property="FontWeight" Value="Bold"/>
         <Setter Property="Foreground" Value="Orange"/>
         <Setter Property="Margin" Value="30"/>
     </Style>

</UserControl.Resources> 

Následně pak přiřadíme k našim TextBlockům, jaký styl mají používat.

<TextBlock x:Name="mujTextBox"
    Text="Silverlight 2.0"
    Style="{StaticResource stylTextBlocku}"/>

<TextBlock x:Name="mujTextBox"
    Text="nemá ve znaku oranžovou"
    Style="{StaticResource stylTextBlocku}"/> 

V tomto případě, na rozdíl od předchozího příkladu, nebude nápis oranžovo-modrý, ale čistě oranžový. Zde se dostáváme k jedné zásadní věci – pokud máte nastavený nějaký zdroj stylování, tak ho kdykoli můžete u komponenty samotné „přepsat“. To znamená, že pokud definujeme u druhého TextBlocku barvu, tak je předdefinovanému stylu nadřazená.

<TextBlock x:Name="mujTextBox"
       Text="Silverlight 2.0"
       Style="{StaticResource stylTextBlocku}"/>

<TextBlock x:Name="mujTextBox"
       Text="nemá ve znaku oranžovou"
       Style="{StaticResource stylTextBlocku}"
       Foreground="LightBlue"/> 

Pokud budeme chtít definovat styly pro celou aplikaci a nejen pro jednu stránku, umístíme je do souboru App.xaml, kde již po vytvoření projektu je připraven koš na zdroje celého projektu.

Kde definovat styly pro celou aplikaci

Šablony

U většiny komponent si vystačíme se stylováním. Představme si ale situaci (a ta nastane), že budeme chtít nastylovat tlačítko. Jenže my nebudeme chtít změnit jen barvu písma nebo styl písma. My budeme chtít, aby vypadalo kompletně jinak (může vypadat opravdu jakkoliv, třeba jako tučňák).

Abychom dosáhli kompletně jiného vzhledu, musíme vytvořit šablonu. Tu si můžeme definovat přímo v těle tlačítka nebo ve zdrojích. Pro znovupoužití je samozřejmě nutné definovat šablonu ve zdroji.

My nevytvoříme přímo tučňáka, ale budeme trochu skromnější. Princip tvorby šablon si ukážeme na jednoduchém kulatém tlačítku. Nejprve si vytvoříme klasické tlačítko.

<Button x:Name="mojeTlacitko"/> 

Pro tvorbu šablony použijeme nástroj ControlTemlate . V ControlTemplate  si definujeme, jak chceme, aby naše tlačítko vypadalo. V našem případě půjde pouze o elipsu s textem uprostřed.

<ControlTemplate x:Key="mojeSablona" TargetType="Button">
      <Grid Height="100" Width="100">

          <Ellipse x:Name="elipsa"
                   Height="100"
                   Width="100"
                   Fill="#EEEEEE"
                   Stroke="DarkGray"/>

          <TextBlock Text="Stiskni mě!"
                     x:Name="obsahTlacitka"
                     HorizontalAlignment="Center"
                     VerticalAlignment="Center"/>

      </Grid>
</ControlTemplate> 

Tuto šablonu nyní přiřadíme k našemu tlačítku.

<Button x:Name="mojeTlacitko" Template="{StaticResource mojeSablona}"/> 

Pokud si teď zobrazíme naše tlačítko, bude vypadat takto:

Vzhled tlačítka

Zprovoznění tlačítka

Použití šablon má jeden háček. Pokud si nyní myší najedete na naše tlačítko nebo je stisknete, nestane se zhola nic. Problém spočívá v tom, že vytvořením nového tlačítka jsme si přepsali chování, které mělo definované původní tlačítko. To si nyní musíme definovat sami. Pozor, neznamená to, že bychom si přepsali události, které můžeme u komponenty Button vyvolat. Pokud si napíšeme nějakou metodu, kterou bude volat stisknutí, tak sice nic neuvidíme, když ale naše tlačítko stiskneme, metoda se vykoná.

K tomu, aby se nám tlačítko nějak „chovalo“, se napřed naučíme vytvářet animace.

Animace

Důvod, proč jsem sem zařadil tvorbu šablon a animace u tlačítka, je, že většina návodů na tvorbu vlastního vzhledu komponent je tvořena pomocí Expression Blend 2. Je pravda, že tento nástroj velice usnadňuje tvorbu a správu šablon, ale pak se vám stane, že se budete muset podívat do kódu a je dobré rozumět tomu, co pro vás Expression Blend 2 vygeneroval.

Co nyní musíme udělat, aby se naše tlačítko chovalo, jak má? Musíme definovat, co se stane, když na něj najedeme myší, stiskneme nebo vypneme.

Každé tlačítko má v sobě zakořeněno několik stavů:

  • Normal
  • MouseOver
  • Pressed
  • Disabled

My si nyní ukážeme, jak nastavit jednoduché animace pro všechny stavy. Tomuto druhu animování komponent na základě stavů se říká „stavová animace“.

Stavová animace

Kostra animace je poměrně jednoduchá. K obsluze „stavové animace“ nám slouží nástroj VisualStateManager . Ve VisualStateManageru si definujeme, kterou skupinu stavů chceme definovat. V našem případě to budou stavy základní – CommonStates. Jednotlivé stavy pak definujeme pomocí VisualState .

Struktura naší animace bude velice jednoduchá. Pro definování skupiny animací použijeme Storyboard . Pro animaci použijeme nástroj DoubleAnimation . Tento nástroj nám umožňuje plynulý přechod mezi dvěma proměnnými Double. Struktura samotné animace je jednoduchá – nastavíte jaký typ komponenty budete animovat, jakou její vlastnost budete animovat, do jaké hodnoty se má během animace dostat a jak dlouho bude celá animace trvat.

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="CommonStates">
        <VisualState x:Name="Normal">
            <Storyboard>
                <DoubleAnimation To="11"
                                 Duration="00:00:00.1"
                                 Storyboard.TargetName="obsahTlacitka"
                                 Storyboard.TargetProperty="FontSize"/>
            </Storyboard>
        </VisualState>
        <VisualState x:Name="MouseOver">
            <Storyboard>
                <DoubleAnimation To="16"
                                 Duration="00:00:00.1"
                                 Storyboard.TargetName="obsahTlacitka"
                                 Storyboard.TargetProperty="FontSize"/>
            </Storyboard>
        </VisualState>


        <VisualState x:Name="Pressed">
            <Storyboard>
                <DoubleAnimation To="14"
                                 Duration="00:00:00.1"
                                 Storyboard.TargetName="obsahTlacitka"
                                 Storyboard.TargetProperty="FontSize"/>
                <DoubleAnimation To=".3"
                                 Duration="00:00:00.1"
                                 Storyboard.TargetName="obsahTlacitka"
                                 Storyboard.TargetProperty="Opacity"/>
            </Storyboard>
        </VisualState>


        <VisualState x:Name="Disabled">
            <Storyboard>
                <DoubleAnimation To=".3"
                                 Duration="00:00:00.1"
                                 Storyboard.TargetName="elipsa"
                                 Storyboard.TargetProperty="Opacity"/>
                <DoubleAnimation To=".3"
                                 Duration="00:00:00.1"
                                 Storyboard.TargetName="obsahTlacitka"
                                 Storyboard.TargetProperty="Opacity"/>
            </Storyboard>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups> 

Pokud si spustíme náš projekt, uvidíme interaktivní tlačítko, viz online ukázka.

K dispozici máte i zdrojový kód ukázky: Demo tvorby šablon v Silverlightu (DOC 509234 bytů).

Závěrem

Principy stylování v Silverlightu jsou velice podobné CSS. Můžete styly definovat u každé komponenty zvlášť nebo si je předdefinovat. Šablony se využívají tehdy, pokud chceme vytvořit vlastní vzhled komponenty. Nesmíme však zapomenout v případě že definujeme vlastní šablonu, také dodefinovat její chování.

Příště

V příštím článku se budeme věnovat základům 2D grafiky v XAMLu. Podíváme se na zoubek základním geometrickým tvarům a na práci s nimi.

Zdroje

Vytváříte tlačítka s vlastním vzhledem?

Autor pracuje ve společnosti Sprinx Systems a.s. jako Project Manager ve „webařské“ skupině.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 11

Přehled komentářů

Věra Pohlová stará dobrá ruční práce
Jan Jelínek Re: stará dobrá ruční práce
Věra Pohlová Re: stará dobrá ruční práce
Jan Jelínek Re: stará dobrá ruční práce
VfB Re: stará dobrá ruční práce
Štěpán Bechynský Re: stará dobrá ruční práce
skrat Moonlight
skrat Re: Moonlight
Martin Hassman Re: Moonlight
Anonym Re: Moonlight
Jan Jelínek RE: Design se styly a šablonami v Silverlightu 2.0
Zdroj: https://www.zdrojak.cz/?p=2931