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).

Kenad URL-id Silverlight rakendustes

Postituses Navigatsioon ja linkimine näitasin kuidas rakendustes XAML lehtede vahel navigeerida. Üheks miinuseks oli see, et vaikimisi nägime aadressiribal reaalset teed failini, mida me alati teha ei taha – esiteks võib siis ju ära arvata linke igasugustele teistele lehtedele ja teiseks ei ole nii eriti ilus ka. Nüüd vaatame, kuidas teha URI-d täpselt nii ilusaks nagu ise tahame. Nimetatakse seda URI mappinguks.

Minu arust on kõige mõistlikum URI mappingud panna App.xaml faili, sest see on ju ometi info, mis käib kogu rakenduse, mitte ainult ühe vaate kohta. Seega, eeldusel, et meil on App.xaml faili päises viide navigatsiooniraamistiku nimeruumile:

xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"

Saame kirjutada midagi sellist:

<Application.Resources>
    <navigation:UriMapper x:key="myUriMapper">
         <navigation:UriMapping Uri="About" MappedUri="/Views/About.xaml" />
    </navigation:UriMapper>
</Application.Resources>

See tähendab, et kui kirjutame aadressiks /MinuLaheRakendus/About näidatakse meie navigatsiooni raamis (Frame objekti sees) About.xaml sisu.

Mustrid

Veel toredamaks teevad asja wildcardid, ehk kirjutades reeglisse {page}

<Application.Resources>
    <navigation:UriMapper x:key="myUriMapper">
         <navigation:UriMapping Uri="About" MappedUri="/Views/About.xaml" />
         <navigation:UriMapping Uri="{page}" MappedUri="/Views/{page}Page.xaml" />
    </navigation:UriMapper>
</Application.Resources>

See tähendab, et kui nüüd kirjutada aadressiks /MinuLaheRakendus/MidaIganes saame sisuks /Views/MidaIganesPage.xaml, ehk me ei pea igakord reegleid juurdetekitama, kui mõni leht juurde sigineb. Reegleid kontrollitakse ülevalt alla ning kasutatakse esimest, mis leitakse, seega kuigi meil on reegel {} => {}page.xaml saame About puhul siiski About.xaml sisu.

Mitu mustrit korraga

Wildcarde võib loomulikult ka kombineerida:

<Application.Resources>
    <navigation:UriMapper x:key="myUriMapper">
         <navigation:UriMapping Uri="About"
                                MappedUri="/Views/About.xaml" />
         <navigation:UriMapping Uri="{page}"
                                MappedUri="/Views/{page}Page.xaml" />
         <navigation:UriMapping Uri="toode/{id}"
                                MappedUri="/Views/Toode.xaml?id={id}" />
         <navigation:UriMapping Uri="{aasta}/{kuu}/{paev}"
                                MappedUri="/Views/Blog.xaml?y={aasta}&amp;m={kuu}&amp;d={paev}" />
    </navigation:UriMapper>
</Application.Resources>

OOB rakenduste uuendusmudel.

OOB ehk Out Of Browser rakendused on need, mille saab paigaldada oma arvutisse. Väga lahe on see, et kui siis hiljem seal algses veebikeskkonnas oma rakendust uuendada, siis uuendatakse automaatselt ka kõikide klientide arvutite koopiad. Kui seda paluda:

public App() {
    this.Startup += this.Application_Startup;

    this.UnhandledException += this.Application_UnhandledException;
    InitializeComponent();

    if (Application.Current.IsRunningOutOfBrowser){
       App.Current.CheckAndDownloadUpdateAsync();
    }
}

Sketchflow 2 – Rakenduse struktuur paika

Struktuur

Esimene, mis peale Sketchflow prototüübi projekti loomist silma hakkab, on Sketchflow Map. Sketchflow kaardi peal on näha, kuidas rakenduse erinevad osad omavahel seotud on – millisest vaatest millisesse liikuda saab. Kui vaateid on palju, siis võib neid gruppeerida määrates neile erinevaid värve. Seda sama kaarti näeb hiljem ka klient (SL puhul veebilehitsejas) prototüüpi üle vaadates.

YATA seaded Sketchflow 2   Rakenduse struktuur paika

Visandamine

Picture 8Iga kord, kui lisame kaardile uue vaate, luuakse taustal selle kohta üks XAML fail, neid faile muutes muudame siis reaalselt prototüüpi ennast. See käib väga sarnaselt tavalise SL rakenduse loomisele – tuleb lihtsalt tööriistade seast õiged elemendid töölauale lohistada. Lisaks on tervitatav ka see, et kui vaja võib ka XAML koodi muuta, vaevalt muidugi, et mõni disainer seda väga teha tahaks :) Selleks, et visand liiga peen välja ei näeks ning klient ei hakkaks arvama, et rakendus juba valmis on. Selleks on Sketchflow-ga kaasas WigglyLines stiil, mis teeb kõikide elementide väljanägemise selliseks lapiskuks, lohakaks kritselduseks. Silverlight ja stiilid töötavad aga teatavasti nõnda, et siis kui hiljem on vaja, et rakendus näeks viimistletud välja, siis on vaja teha ainult paar hiireklikki ja vana kritseldus asendada õige disainiga.

Navigatsioon

YATA navigateTO Sketchflow 2   Rakenduse struktuur paika

Liikumaks rakenduse ühest osast teise, piisab sellest, et valime vaates mõne objekti või nupu, teeme sel paremkliki ning valime valikust Navigate to vaate nime, mida järgmisena näitama peaks. Minnes tagasi kaardi juurde, siis sealt võime valida ükskõik millise ühendusjoone ning täpsustada, milline animatsioon peaks nende vaadete vahel liikumisele kaasnema. Siis on peenem, kliendile kindlasti meeldib :)

Kokkuvõte

Sketchflowga võib väga kiiresti saada päris hea tulemuse – poole tunniga võib saada struktuuri ning kõik vaated  paika ning esimese tagasiside kätte, kas see on umbes see, mida vaja. Siis edasi võib juba minna enam detailidesse – lisada näidisandmeid ning kujundada täpselt välja kõik andmelistid, toodete nimekirjad jne. Näidisandmed ongi need, millega järgmine postitus Sketchflow seerias tegeleb.

ListBoxi hiirega kerimine

Üks Silverlighti nõrk külg on see, et igasuguste loetelude hiirega kerimine vaikimisi ei tööta. Sellest puudusest müüda saamiseks leidub erinevates foorumites päris mitmeid lahendusi, kuid enamus neist on üsna keerulised ja eeldavad palju koodi kirjutamist. Hiljuti õnnestus mul aga üks selline lahendus leida, mida on hästi lihtne implementeerida.

Keritav ListBox

Oletame, et meil on järgmine värvide nimesid sisaldav ListBox:

image thumb13 ListBoxi hiirega kerimine

Siis üks võimalus see keritavaks muuta on panna see ScrollViewer-i sisse. Selleks tuleb parema klahviga vajutada ListBoxi peal ja valida sealt Group Into > ScrollViewer.

image thumb14 ListBoxi hiirega kerimine

Tulemus võiks olla midagi sellist:

image thumb15 ListBoxi hiirega kerimine

Hiire toe lisamine

Hiirega kerimise jaoks on vaja alla laadida ja lahti pakkida SharpGISBehaviors. Selle kasutamiseks tuleb projekti lisada veel viide SharpGIS.Silverlight.Behaviors\BehaviorTests\Bin\Debug\SharpGIS.Silverlight.Behaviors.dll failile

image thumb16 ListBoxi hiirega kerimine

ja lohistada MouseScrollViewer varem loodud ScrollVieweri peale.

scroll thumb ListBoxi hiirega kerimine

Ongi valmis!

Demo

Faili allalaadimise dialoog

Veel üks Silverlight 3 uus feature on võimalus lihtsalt luua faili allalaadimise dialoog.image thumb10 Faili allalaadimise dialoog

Selleks tuleb kõigepealt muidugi luua nupp ja sellele vastav event.

image thumb11 Faili allalaadimise dialoog image thumb12 Faili allalaadimise dialoog

Save_Click meetodis tuleb kõigepealt luua uus SaveFileDialog:

SaveFileDialog dialog = new SaveFileDialog()

Järgmisena tuleb ära määrata salvestava faili tüüp. See ei ole küll kohustuslik, aga teeb kasutajal elu mugavamaks. Eriti kui on teada, et salvestatakse näiteks ainult tekstifaile.

{
DefaultExt = "txt",
Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*",
FilterIndex = 1
};

Viimasena tuleb paika panna see, kuidas info sinna salvestatavasse faili saab.

bool? dialogResult = dialog.ShowDialog();
if(dialogResult == true){
    StreamWriter writer = new StreamWriter(dialog.OpenFile());
    foreach (string el in selectedList){
        writer.WriteLine(el);
    }
    writer.Dispose();
    writer.Close();
}

Oma sõnaraamatu puhul hoiame me kõiki sõnu List<string> tüüpi muutujas selectedList ja see kood võtabki siis kõik seal listis olevad sõned ja kirjutab need faili.

Lõpuks veel kogu Save_Click meetod:

private void Save_Click(object sender, System.Windows.RoutedEventArgs e)
{
    SaveFileDialog dialog = new SaveFileDialog()
    {
        DefaultExt = "txt",
           Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*",
        FilterIndex = 1
    };

    bool? dialogResult = dialog.ShowDialog();
    if(dialogResult == true){
        StreamWriter writer = new StreamWriter(dialog.OpenFile());
        foreach (string el in selectedList){
            writer.WriteLine(el);
        }
        writer.Dispose();
        writer.Close();
    }
}

Rakenduse ikoonide muutmine

Ühes varasemas postituse rääkisime sellest, kuidas Silverlight rakendust brauserist väljaspool tööle panna. Kes selle ise järgi proovisid, siis võib-olla märkasid, et vaikimisi on iga rakendus ikoon midagi sellist:

image thumb5 Rakenduse ikoonide muutmine

See ei ole küll kole ikoon, aga ikka tahaks ju enda rakenduse teistest eristamiseks midagi huvitavamat. Tuleb välja, et see on täiesti võimalik, kuigi Expression Blendi kasutades natuke keerulisem kui arvata võiks.

Ikoonide ettevalmistamine

Silverlight tahab ikoone saada neljas erinevas suuruses ja PNG formaadis. Nõutuavad suurused on 16×16, 32×32, 48×48 ja 128×128 pikslit. Meie kasutasime piltide erinevatesse suurustesse salvestamiseks Painti, kuigi selleks on ilmselt ka paremaid rakendusi, sest Paint kaotab PNG failide salvestamisel ära läbipaistvuse ja tekib natuke häiriv valge taust. Meie ikoonid olid näiteks sellised:

16×16 32×32 48×48 128×128
16x16 thumb Rakenduse ikoonide muutmine 32x32 thumb Rakenduse ikoonide muutmine 48x48 thumb Rakenduse ikoonide muutmine 128x128 thumb Rakenduse ikoonide muutmine

Kindlasti on vajalikud kõik eri suurustest failid, sest neid näidatakse erinevates kohtades (Start-menüü, töölaud jne.).

Failide projekti lisamine

See on Expression Blendis kõige keerulisem samm ja selle tööle saamiseks kulus mul ikka päris mitu tundi, sest internetist ei õnnestunud ühtegi juhendit ka leida. Visual Studios oleks see ilmselt palju lihtsamalt käinud ja VS kohta leidub netis ka päris palju juhendeid.

Kõigpealt tuleb luua projekti alla uus kaust, mida saab teha näiteks niimoodi:

image thumb6 Rakenduse ikoonide muutmine

Järgmisena tuleb vajutada parema klahviga loodud kaustal ja valida Add Existing Item…

image thumb7 Rakenduse ikoonide muutmine

Avanenud aknas tuleks üles otsida päris alguses loodud ikoonid ja need sinna kausta lisada. Tulemus võiks näha välja midagi sellist:

image thumb8 Rakenduse ikoonide muutmine

Build actioni muutmine

Järgmine samm ongi kõige keerulisem, sest kui niimoodi faile lisada, siis paneb Expression Blend build actioni väärtuseks Resource, aga ikoonide puhul peab see olema Content. Lisaks ei ole võimalik kasutajaliideses seda kuidagi muuta. Lahenduseks on see, kui minna Windows Exporeriga projekti kausta ning avada suvalise tekstiredaktoriga ProjektiNimi.csproj fail. Minul asub see näiteks sellises kohas:

C:\Users\alasoo\Documents\Expression\Blend 3\Projects\SilverlightApplication1\SilverlightApplication1

Kui see fail on avatud, siis tuleb sealt üles otsida pildifailide kohta käivad read

<Resource Include="icons\128x128.png" />
<Resource Include="icons\16x16.png" />
<Resource Include="icons\32x32.png" />
<Resource Include="icons\48x48.png" />

ja neis sõna Resource asendada sõnaga Content:

<Content Include="icons\128x128.png" />
<Content Include="icons\16x16.png" />
<Content Include="icons\32x32.png" />
<Content Include="icons\48x48.png" />

Nüüd peaks olema kõik failid õigesti projekti lisatud.

Ikoonide asendamine

Ikoonide asendamiseks tuleb avada meile juba tuttav OutOfBrowserSettings.xml fail ja lisada sinna järgmised read:

<OutOfBrowserSettings.Icons>
    <Icon Size="16,16">icons/16x16.png</Icon>
    <Icon Size="32,32">icons/32x32.png</Icon>
    <Icon Size="48,48">icons/48x48.png</Icon>
    <Icon Size="128,128">icons/128x128.png</Icon>
</OutOfBrowserSettings.Icons>

Kui nüüd järgmine kord rakendust installeerima hakata, siis on ikoon juba muutunud.

image thumb9 Rakenduse ikoonide muutmine

Brauserivälise rakenduse loomine

Üks Silverlight 3-e uusi omadusi on see, et nüüd on võimalik luua ka selliseid rakendusi, mis töötavad brauserist väljaspool.  Väga kasulik on see näiteks selliste programmide puhul, mis töötamiseks tingimata internetiühendust ei vaja, nagu näiteks meie Home Reading Helper sõnaraamaturakendus.

Alustamine

Esimene samm on Expression Blend 3-s väga lihtne. Tuleb lihtsalt avada oma projekt ja valida ülevalt menüüst Project > Silverlight Project Preferences > Enable Application Outside Browser.

image thumb Brauserivälise rakenduse loomine

Kui nüüd Run Project teha, siis on peale rakenduse laadimist võimalik sellel parema klahviga vajutada ja see oma arvutisse paigaldada.

image thumb1 Brauserivälise rakenduse loomine

Seadistamine

Kui nüüd aga rakendus käima panna, siis võib märgata, et akna suurus on vale ja nimi ei ole ka päris selline nagu ta olla võiks.

image thumb2 Brauserivälise rakenduse loomine

Nende vigade parandamiseks tuleb muuta OutOfBrowserSettings.xml faili, mis asub Properties kaustas.

image thumb3 Brauserivälise rakenduse loomine

Selle sisu näeb tavaliselt välja umbes järgmine:

<?xml version="1.0" encoding="utf-8" ?>
<OutOfBrowserSettings ShortName="SilverlightApplication1" EnableGPUAcceleration="True">
    <OutOfBrowserSettings.Blurb>
        A short description of the application.
    </OutOfBrowserSettings.Blurb>
    <OutOfBrowserSettings.WindowSettings>
        <WindowSettings Height="600" Width="800" Title="SilverlightApplication1" />
    </OutOfBrowserSettings.WindowSettings>
</OutOfBrowserSettings>

Meile piisab sellest, kui muuta natuke 7. rida ja kirjutada sinna näiteks:


<WindowSettings Height="480" Width="640" Title="Home Reading Helper" />

Lõpptulemus on juba palju ilusam.

image thumb4 Brauserivälise rakenduse loomine

Ongi valmis!

Brauserivälised rakendused töötavat nii Windowsi kui ka Maciga (kuigi esmapilgul natuke aeglasemalt). Kuna Moonlight veel Silverlight 3-e ei toeta, siis selle operatsioonsüsteemi kasutajad on hetkel natuke kõrvale jäetud.

Minu esimene Silverlight rakendus

Nagu postituse ülemisest äärest näha on, siis ei ole ma Jaana, vaid olen hoopis Kaur.  Viimasel ajal olen ma põhiliselt kirjutanud MUG.ee blogisse.  Nädal aega tagasi hakkasin ma ilma igasuguse varasema kogemuseta Jaana abiga ehitama oma esimest Silverlight rakendust. Nüüd, kui programm peaaegu valmis on, mõtlesin õpitust ka siin blogis natuke kirjutada.

Millega on tegu?

Umbes aasta tagasi võtsin ma ülikoolis saksa keelt ning selle aine raames oli meil vaja üsna palju lugeda ja tõlkida. Kuna ma aga ei viitsinud uusi sõnu käsitsi välja kirjutada, siis mõtlesin, et võiks olla selline sõnaraamatu rakendus, kus oleks võimalik ühe hiireklikiga otsitud sõnu salvestada. Selle tulemusena sündis üks hästi kole PHP-rakendus mis parsis BEOLINGUS-e veebisõnastikku.

Kuna ma ei olnud juba algusest saati sellega rahul ning mingil hetkel läks see paratamatult katki ka (BEOLINGUS muutis oma veebilehe struktuuri),  siis otsustasin lõpuks asja kätte võtta.

hrh thumb Minu esimene Silverlight rakendus

Home Reading Helper on lihtne sõnaraamat, kust saab sõnu otsida ja neil klikkides huvitavaid sõnu välja valida. Töö lõpetades saab kõik välja valitud sõnad tekstifailina kettale salvestada. Keeltest on hetkel toetatud eesti-inglise-eesti (eki.ee) ja saksa-inglise-saksa (freedict.de).

Kuidas tehtud?

Lähipäeval kirjutan ma kõigist olulisematest ja huvitavamatest sammudest eraldi postitused ja lisan viited neile ka siia. Sõnade otsimine on realiseeritud ühe varasema Jaana postituse põhjal.