4. díl - Programujeme pro Windows 8 - Navigace mezi stránkami

C# .NET Windows Store Aplikace Programujeme pro Windows 8 - Navigace mezi stránkami

Vítám vás u 4.dílu seriálu Programujeme pro Windows 8. V minulém díle jsme si dokončili první aplikaci ve stylu Hello World. Dnes se podíváme na mnohem zajímavější základy a tím je navigace mezi stránkami a příště na obsluhu app-life, tedy obsluhu stavů aplikace.

Pro dnešní tutoriál začneme zcela s novou aplikací. Bude se jednat o zcela nesmyslnou aplikaci, která nám ovšem postačí pro dnešní účely. Aplikace bude mít dvě stránky, první a úvodní stránka nabídne tři textboxy. Každý textbox bude sloužit pro jiný typ uložení/posílání dat. Druhá stránka nabízí pouze textblock, který zobrazí pozdrav z první stránky.

Příprava

Nebudeme se zatěžovat vytvořením struktury aplikace. Použijeme sice komponentu, kterou jsme ještě nepoužívali a používáme i nadefinovaný styl, ale dnes si s tím nelámejte hlavu. Vysvětlíme si to jindy :). Následující kód nakopírujte do hlavního Gridu, jako v minulém díle jsme přidali naše dvě komponenty.

<Grid Grid.Row="1">
          <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
              <Grid>
                  <Grid.RowDefinitions>
                      <RowDefinition Height="*"/>
                      <RowDefinition Height="*"/>
                      <RowDefinition Height="*"/>
                      <RowDefinition Height="*" />
                  </Grid.RowDefinitions>
                  <Grid.ColumnDefinitions>
                      <ColumnDefinition Width="Auto"/>
                      <ColumnDefinition Width="Auto" />
                  </Grid.ColumnDefinitions>

                  <TextBlock Text="Jméno" Style="{StaticResource TextStyle}" />
                  <TextBox x:Name="txName" Grid.Column="1" Width="150" Margin="25,0,0,0" />
                  <TextBlock Text="Věk" Grid.Row="1" Style="{StaticResource TextStyle}" Margin="0,15,0,0" />
                  <TextBox x:Name="txVek" Grid.Row="1" Grid.Column="1" Width="150" Margin="25,15,0,0" />
                  <TextBlock Text="Pozdrav kolegu" Grid.Row="2" Grid.ColumnSpan="2" Style="{StaticResource TextStyle}" Margin="0,15,0,0" HorizontalAlignment="Center" />
                  <TextBox x:Name="txPozdrav" Grid.Row="3" Width="180" Margin="0,15,0,0" />
                  <Button x:Name="btnOdeslat" Content="Poslat" Grid.Row="3" Grid.Column="1" Margin="0,15,0,0" HorizontalAlignment="Center" Click="btnOdeslat_Click" />
              </Grid>
          </StackPanel>
      </Grid>

Pouze v rychlosti. Přidali jsme (jak mám ve zvyku) další grid do druhého řádku hlavního gridu. V gridu máme stackpanel, další grid a další potřebné komponenty.

Otevřete si MainPage.xaml.cs a přidejte metodu pro obsluhu události kliknutí na tlačítko.

private void btnOdeslat_Click(object sender, RoutedEventArgs e)
{

}
Vzhled první stránky

Vzhled první stránky

Hlavní stránka je připravena, přidáme druhou stánku. Klikněte pravým na název projektu, Add -> Add new item -> Basic page. Pojmenujte ji KecalPage. Na druhou stránku přidejte následující kód. Jedná se pouze o Grid, Stackpanel (ačkoliv mírně zbytečný) a TextBlock pro zobrazení zprávy.

<Grid Grid.Row="1">
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
        <TextBlock x:Name="txPrijato" FontSize="40" />
    </StackPanel>
</Grid>

Fajn, vše je připraveno pro lepší zábavu.

Navigace

Ukážeme si jednoduchou navigaci stránek. Po kliknutí na tlačítko se přesunume na námi druhou vytvořenou stránku KecalPage. Do metody obsluhující kliknutí přidejte následující řádky.

if (txPozdrav.Text != string.Empty)// není textbox prázdný ?
{
    // navigace na další stránku a poslání objektu
    // v našem případě string z textboxu
    this.Frame.Navigate(typeof(KecalPage), txPozdrav.Text);
}

Nejdříve zkontrolujeme, zda textbox txPozdrav není prázdný. Když obsahuje text, přesuneme se na další stránku. Navigaci obsluhujeme přes třídu Frame, která mimo metody Navigate, obsahuje i metody GoBack,GoForwar­d, GoHome apod. Prvním parametr metody je povinný a udává typ stránky, na kterou se přesouváme. Druhý parametr je nepovinný a dovoluje nám poslat libovolný objekt na stránku. V našem případě posíláme text z textboxu txPozdrav.

Přesuňte se do KecalPage.xaml.cs. Přepíšeme si metodu OnNavigatedTo, kterou nám poskytuje předek LayoutAwarePage. Zde vidíme první výhodu přidání pomocných tříd, který jsme si popsali v druhém díle, řeší za nás velmi snadno navigaci a jak uvidíte v příštím díle tak i ukládání dat. Přepíšeme tedy metodu

protected override void OnNavigatedTo(NavigationEventArgs e)
{

    base.OnNavigatedTo(e);
}

Zavolání metody z předka base.OnNaviga­tedTo(e) je nutné nechat! Metoda se zavolá při otevření stránky, při navigování z jiné stránky. Argument e nám poskytuje zjištění zdrojové stránky navigace, adresu nebo námi předaný objekt Parameter. Nastavíme tedy text textblocku txPrijato.

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    if (e.Parameter != null)
    {
        txPrijato.Text = e.Parameter.ToString();
    }
    base.OnNavigatedTo(e);
}

Pro jistotu si přidáme podmínku, zda není předaný objekt null. Zkuste si nyní aplikaci zapnout, vyplnit pozdrav a přesunout se na stránku.

Mělo by vše fungovat jak má. Zkuste si pohrát s třídou Frame. Podívejte se na další metody, které nám poskytuje předek, například OnNavigatedFrom, která se hodí pro zjištění, že stránku opouštíme. Nespornou výhodu nám poskytuje předání libovolného objektu, které lze velmi dobře využívat.

Abychom trochu zaplnili obsah dnešního článku, pojďme si aplikaci do příště trochu vymalovat. Jako první změníme styl písma. Nalezněte si v Page.Resources definici stylu pro všechny TextBlocky.

<Style x:Key="TextStyle" TargetType="TextBlock">
            <Setter Property="FontSize" Value="30"/>
        </Style>

Stylům se budeme věnovat i v samostatném článku. Prozatím stačí vědět, že zde definujeme lokální styl stránky, který je určen pouze pro komponenty TextBlock. Máme zde pouze jednu nastavenou vlasnost a tou je FontSize (Velikost písma) na 30. Přidáme si definici FontFamily (Rodina písma). Zvolil jsem tento Segoe Print. Vlasnost přidáme hned pod definici vlasnosti FontSize

<Setter Property="FontFamily" Value="Segoe Print" />

Nyní máme o něco malinko hezčí aplikaci. Určitě jste pochopili, jak nastavovat základní styly. Zkuste si sami vytvořit styl pro TextBoxy, které budou mít například stejné pozadí.

Výsledný vzhled aneb takhle design nemá vypadat

Výsledný vzhled aneb takhle design nemá vypadat

To je přátelé pro dnešek vše. Opět jsme nestihli mnoho a příště se podíváme na první část ukládání dat a stavů aplikace. Schválně si zkuste jedno. Vyplňte všechny TextBoxy a přesuňte se na druhou stránku. Pokochejte se textem uprostřed obrazovky a vraťte se zpět. A máme problém, vyplněné TextBoxy jsou prázdné. Proč a jak je nechat vyplněné si řekneme příště :).

Doufám, že vás dnešní díl alespoň trochu zaujal a těším se na vlnu komentářů, tipů a kritiky. Uvidíme se příště!


 

Stáhnout

Staženo 253x (280.42 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

  Aktivity (1)

Článek pro vás napsal Petr Nymsa
Avatar
Autor se věnuje programování v C# a celkově se zajímá o .NET technologie. Působí jako Microsoft Student Partner.

Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!


 



 

 

Komentáře
Zobrazit starší komentáře (13)

Avatar
Petr Nymsa
Redaktor
Avatar
Petr Nymsa:

Ahoj, koukni na model MVVM, nad všemi stránkami si budeš držet data aplikace. A budeš k nim moct přistupovat odkudkoliv :) .... zatím ti to píšu takto stručně, o MVVM je spousta článků, každopádně se neboj zeptat

Odpovědět 3.9.2013 17:27
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
petrzywczok
Člen
Avatar
petrzywczok:

No tak jsem se na to vytváření po delší době vrhl a nějak si nevím rady. Momentálně řeším tohle: mám vytvořenou instanci ViewModelu na jedné stránce, kde ukládám do ObservableCollec­tion data a ty data bych teď chtěl zobrazit na jiné stránce. Zkoušel jsem tu instanci předat do konstruktoru na další stránce, ale to pak zase nevím, jak pořešit navigaci, protože když upravím konstruktor nějak takhle: public Okno2(Spravce­Vlastnosti spravcevlastnos­ti){Initialize­Component(); Datacontext = spravcevlastnos­ti;} tak mi nefunguje navigace na tu stránku pomocí this.Frame.On­Navigate(type­of(Okno2)), spravcevlastnos­ti)... Nemáte někdo ponětí, proč to tak nefunguje, případně jak to udělat?

 
Odpovědět 25.1.2014 15:40
Avatar
petrzywczok
Člen
Avatar
Odpovídá na petrzywczok
petrzywczok:

ještě oprava, má tam být napsáno this.Frame.Na­vigate... ale tak to mám a nefunguje

 
Odpovědět 25.1.2014 16:05
Avatar
Hammy350
Člen
Avatar
Odpovídá na petrzywczok
Hammy350:

Radši používej code, takhle se na ten kód blbě dívá

 
Odpovědět 25.1.2014 17:08
Avatar
petrzywczok
Člen
Avatar
petrzywczok:

OK, použiji to v tomhle příspěvku :). Nakonec jsem si řekl, že si ty data prostě uložím do xml a načtu je na té další stránce, ale bohužel zase někde chyba. Mám to takhle:

public void Uloz()
{
        XmlSerializer serializer = new XmlSerializer(Neco.GetType());
        using (StreamWriter sw = new StreamWriter("neco.xml"))
        {
                serializer.Serialize(sw, Neco);
        }
}

a teď mi pro změnu vyskakuje chyba na místě, na kterém mi to nedává smysl a to pří zápisu ve StreamWriter("ne­co.xml") - píše mi to "některé argumenty přetěžované metody jsou neplatné"

 
Odpovědět 25.1.2014 22:40
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na petrzywczok
Jan Vargovský:

Zkus nám tu dát celou vyjímku i s těmi třídami, které chceš serializovat.

 
Odpovědět 25.1.2014 22:46
Avatar
petrzywczok
Člen
Avatar
petrzywczok:

Takže třída co serializuju je tato:

public class Automobil
    {
        public string SPZ { get; set; }
        public string NazevVozu { get; set; }
        public string STK { get; set; }

        public Automobil() { }

        public Automobil( string spz, string nazevVozu, string stk )
        {

            SPZ = spz;
            NazevVozu = nazevVozu;
            STK = stk;
        }

Tady s ní pak pracuju:

public class SpravceAutomobil
    {
        public ObservableCollection<Automobil> Automobily { get; set; }

        public SpravceAutomobil()
        {
                Automobily = new ObservableCollection<Automobil>();
        }

        public void Pridej(string spz, string nazevVozu, string stk )
        {
            if (spz == "")
                throw new ArgumentException("SPZ nebyla zadána");
            if (nazevVozu == "")
                throw new ArgumentException("Nebylo zadáno jméno vozu");
            if (stk == "")
                throw new ArgumentException("Datum nebylo zadáno");
            Automobil automobil = new Automobil( spz, nazevVozu, stk );
            Automobily.Add(automobil);
        }


        public void Uloz()
        {
            XmlSerializer serializer = new XmlSerializer(Automobily.GetType());
            using (StreamWriter sw = new StreamWriter("automobily.xml"))
            {
                serializer.Serialize(sw, Automobily);
            }
        }

No a tohle mi to hlásí v rámci StreamWriter: Chyba 1 Některé argumenty přetěžované metody, která je nejlepší shodou pro deklaraci System.IO.Stre­amWriter.Stre­amWriter(System­.IO.Stream), jsou neplatné. Chyba 2 Argument 1: Nelze převést z typu string na typ System.IO.Stream.

Editováno 25.1.2014 23:03
 
Odpovědět 25.1.2014 23:02
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na petrzywczok
Jan Vargovský:

Zajimavé. První přetížení třídy StreamWriter je tuším, že bere stream jako typ a druhé je že bere string. Zkus napsat to vytvoření instance sw znova :) asi visualko trošku blbne :)

 
Odpovědět 25.1.2014 23:07
Avatar
petrzywczok
Člen
Avatar
petrzywczok:

To bohužel nepomáhá... ani když jsem praštil do PC :-). Nicméně mě to celkem dost štve, protože to potřebuju udělat :-/

 
Odpovědět 25.1.2014 23:38
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na petrzywczok
Jan Vargovský:

No ten kód je v pořádku. Zkus restartnout visualko. Popřípadě využij to další přetížení (třeba http://msdn.microsoft.com/…ary/36b035cb(v=vs.110).aspx) takže dej ještě další parametr false.

 
Odpovědět 25.1.2014 23:44
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 23. Zobrazit vše