Stiilid – uued võimalused SL3 ja SL4s

Stiilide pärimine

Oletame, et meil on stiil Stiil1 ja me tahame teha Stiil2-e, mis sarnaneb esimesele aga on ikkagi pisut teistsugune. Varem tähendas see seda, et Stiil2-ks tuli kopeerida Stiil1 sisu ja siis muutma hakata. Alates juba Silverlight 3-st on võimalik pärimine stiilide vahel.

image thumb11 Stiilid – uued võimalused SL3 ja SL4s

Üldised stiilid

Põhimõtteliselt ei ole ju keeruline kirjutada nupu juurde <Button x:Name="startButton" Style="{StaticResource Stiil1}", samas kui kõik minu nupud peakski täpselt sellised välja nägema nagu selles stiilis kirjeldatud, siis oleks nagu tüütu.

Kui stiili definitsiooni juures eemaldada atribuut x:Key, siis on selle stiiliga kõik rakenduse või konkreetse XAML lehe seda tüüpi objektid – näiteks nupud. See kas üldine stiil mõjub üle rakenduse või üle ühe XAML faili sõltub sellest, kas stiil on defineeritud App.xaml (mõjub üle rakenduse) või mõnes muus XAML failis (mõjub ainult selle faili nuppudele).

Stiilid

Veebilehed koosnevad hulgast erinevast komponendist – nupud, tekstikastid, pildid, videod jms. Igaühel neist on hulk atribuute, mis kirjeldavad nende välimuse – kõrgus, laius, värv, positsioon jms.

Seni on selle ajaveebi näidetes kõik värlimuskirjeldused kirjutatud (inline) XAML koodi:

<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" 
           TextWrapping="Wrap" Text="Esimene" FontWeight="Bold" 
           FontFamily="Portable User Interface" FontSize="16"            Opacity="0.855" FontStyle="Normal" TextDecorations="Underline">
    <TextBlock.Foreground> 
        <LinearGradientBrush EndPoint="0.915,1.304" StartPoint="0.356,-0.8259"> 
            <GradientStop Color="#FF000000"/> 
            <GradientStop Color="#FFFFFFFF" Offset="1"/> 
            </LinearGradientBrush> 
    </TextBlock.Foreground> 
</TextBlock>

Kui selliseid tekstikaste on üks, siis pole ju väga vigagi aga mis saab siis, kui sarnase välimusega on 10 tekstikasti? Vot siis on vajalike koodiridade hulk juba utoopiline (näiteks 111 rida :) ). Aga sellel on lahendus! Kirjeldame välimuse ühe korra ja edasi vaid viitame sellele :)

Stiili loomine

Stiilid koondatakse tavaliselt rakenduse globaalsete ressursside hulka App.xaml failis – siis on stiilid kasutatavad terve rakenduse piires. Võib kirjutada ka ühe konkreetse objekti ressursside hulka, siis saab teda kasutada tema alamate piires.

Tühjana näeb App.xaml fail välja järgnevalt:

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Class="ProjektiNimi.App">
    <Application.Resources>
    </Application.Resources>
</Application>

Igal stiilil on määratud nimi (x:Key) ning objektide tüüp millele ta mõjub (TargetType).

<Style x:Key="tekstiStiil" TargetType="TextBlock" >
    <Setter Property="FontSize" Value="16"/>  </Style>

Eelnevaga on loodud tekstikasti stiil nimega tekstiStiil, mis määrab (Setter) vaid teksti suuruse (Property=FontSize).

Sama võib kirjutada ka mitmel real, mis on lausa hädavajalik seades tekstivärviks gradienti:

<Setter Property="Foreground">
    <Setter.Value>
                <LinearGradientBrush EndPoint="0.915,1.304" StartPoint="0.356,-0.8259">
                    <GradientStop Color="#FF000000"/>
                    <GradientStop Color="#FFFFFFFF" Offset="1"/>
               </LinearGradientBrush>
    </Setter.Value>
</Setter>

Koondades kõik postituse alguses toodud näite välimuskirjelduse stiili kokku, saame:

<Application xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation 
             xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml              x:Class="ProjektiNimi.App"> 
<Style x:Key="tekstiStiil" TargetType="TextBlock" >
        <Setter Property="FontSize" Value="16"/>
        <Setter Property="HorizontalAlignment" Value="Center"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
        <Setter Property="TextWrapping" Value="Wrap"/>
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="FontFamily" Value="Portable User Interface"/>
        <Setter Property="Opacity" Value="0.85"/>
        <Setter Property="TextDecorations" Value="Underline"/>
        <Setter Property="Foreground">
            <Setter.Value>
                <LinearGradientBrush EndPoint="0.915,1.304" StartPoint="0.356,-0.8259">
                    <GradientStop Color="#FF000000"/>
                    <GradientStop Color="#FFFFFFFF" Offset="1"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
</Style>
</Application.Resources> </Application> 

Stiili kasutegur on näha siin, sest sellise tekstikasti loomiseks on vaja nüüd mitte 110 vaid 10 rida:

<StackPanel>
    <TextBlock Text="Esimene" Style="{StaticResource tekstiStiil}"/>
    <TextBlock Text="Teine" Style="{StaticResource tekstiStiil}"/>
    <TextBlock Text="Kolmas" Style="{StaticResource tekstiStiil}"/>
    <TextBlock Text="Neljas" Style="{StaticResource tekstiStiil}"/>
    <TextBlock Text="Viies" Style="{StaticResource tekstiStiil}"/>
    <TextBlock Text="Kuues" Style="{StaticResource tekstiStiil}"/>
    <TextBlock Text="Seitsmes" Style="{StaticResource tekstiStiil}"/>
    <TextBlock Text="Kaheksas" Style="{StaticResource tekstiStiil}"/>
    <TextBlock Text="Üheksas" Style="{StaticResource tekstiStiil}"/>
    <TextBlock Text="Kümnes" Style="{StaticResource tekstiStiil}"/>
</StackPanel>


Nagu näha, siis elemendile saab stiili määrata kasutades konstruktsiooni

Style="{StaticResource stiiliNimi}"

Muidugi see, et panime stiili paika ei tähenda, et see on kivvi raiutud ja midagi muuta ei saa. Kui on vaja teha ühe elemendi juures üht väikest muudatust – näiteks üks tekstikast peab olema suurem kui teised, siis ikka – nii nagu tavaliselt, lihtsalt lisame selle XAML koodi. Ei pea tegema uut stiili.

<TextBlock Text="Esimene" FontSize="24" Style="{StaticResource tekstiStiil}"/>