Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1906, comments - 2047, trackbacks - 352

My Links

News

Your host

This is me! Questo spazio è dedicato a Microsoft® .NET®, di cui sono molto appassionato :-)

Cookie e Privacy

Disabilita cookie ShinyStat

Microsoft MVP

My MVP Profile

Microsoft Certified Professional

Microsoft Specialist

Xamarin Certified Mobile Developer

Il mio libro su VB 2015!

Pre-ordina il mio libro su VB 2015 Pre-ordina il mio libro "Visual Basic 2015 Unleashed". Clicca sulla copertina per informazioni!

Il mio libro su WPF 4.5.1!

Clicca sulla copertina per informazioni! E' uscito il mio libro "Programmare con WPF 4.5.1". Clicca sulla copertina per informazioni!

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.
If you're not an Italian user, please visit my English blog

Le vostre visite

I'm a VB!

Guarda la mia intervista a Seattle

Follow me on Twitter!

Altri spazi

GitHub
I miei progetti open-source su GitHub

Article Categories

Archives

Post Categories

Image Galleries

Privacy Policy

Sviluppare Metro-style app per Windows 8 con Visual Basic - sesta parte

Dopo una lunga pausa riprendiamo la serie di post dedicati allo sviluppo di app in stile Metro per Windows 8, con il nostro amato Visual Basic.

C'eravamo salutati la volta scorsa dopo aver completato il nostro news reader, dotato di app bar. Questa volta facciamo considerazioni sul layout e sulle rotazioni.

Layout e adattabilità

Sganciamoci per un momento dall'ambiente desktop classico a cui siamo abituati e immaginiamo di avere in mano un tablet. Come sapete, questo può essere ruotato. Ciò implica che il layout della nostra app deve essere in grado di adattarsi alla rotazione. Non solo: in Windows 8 esiste il concetto di Snap che permette di tenere in vita un'app Metro a fianco di quelle desktop. La seguente figura mostra una rappresentazione di un'app in snap:

Lo snap è disponibile solo per risoluzioni da 1366 x 768 in su, ma va comunque tenuto in considerazione. Ecco quindi che in questo post stravolgeremo praticamente tutta la UI del nostro news reader, facendo delle cose necessarie.

Vi ricordo che il codice fino alla quinta parte di questa serie è disponibile a questo indirizzo e vi consiglio di scaricarlo in modo da avere una base da cui partire.

Altra cosa che vi consiglio vivamente è avere sempre al vostro fianco la documentazione MSDN per creare la prima app Metro. Li ci sono cose che useremo in questo post, cose che useremo parzialmente e cose che lì sono fatte in modo più approfondito, per cui vi servirà in futuro.

Stati Visuali

Per cambiare layout a seconda dell'orientamento del device e dello snap si usa un oggetto già noto in WPF e Silverlight, il Visual State Manager. Partendo dalla documentazione sopra linkata, possiamo ricavare un po' di codice adatto allo scopo. Per prima cosa modifichiamo l'oggetto Page in LayoutAwarePage, che si adatta a questi discorsi. In primo luogo aggiungiamo un namespace common a livello di pagina:

xmlns:common="using:adsVBMetroReader.Common"

Quindi modifichiamo l'oggetto Page in common:LayoutAwarePage. All'interno della Grid radice vanno poi aggiunti gli stati visuali, in particolare la gestione degli stati Landscape, Portrait e Snapped. E' importante ricordare che l'oggetto LayoutAwarePage non fa parte di WinRT ma è disponibile tra i file auto-generati dal template di progetto ed offre di default una serie di membri che supportano la navigazione in pagine e che è sufficiente collegare in binding un button al membro GoBack per attivare la navigazione alla pagina precedente. In questo particolarissimo esempio non abbiamo navigazione, quindi negli stati visuali viene reso "innocuo" lo XAML relativo a questo pulsante. In questo preciso momento accompagnatevi nella lettura con la documentazione poichè riporta le motivazioni relative alle altre parti rese innocue. Ecco lo XAML per gli stati visuali:

        <VisualStateManager.VisualStateGroups>
 
            <!-- Visual states reflect the application's view state -->
            <VisualStateGroup>
                <VisualState x:Name="FullScreenLandscape"/>
 
                <!-- Filled uses a simpler list format in a narrower column -->
                <VisualState x:Name="Filled">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="primaryColumn" Storyboard.TargetProperty="Width">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="420"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemListView" Storyboard.TargetProperty="ItemTemplate">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource NarrowListItemTemplate}"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemDetail" Storyboard.TargetProperty="Padding">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="60,0,66,0"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
 
                <!--
                    The page respects the narrower 100-pixel margin convention for portrait, and the page
                    initially hides details to show only the list of items
                -->
                <VisualState x:Name="FullScreenPortrait">
                    <Storyboard>
                        <!--<ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PortraitBackButtonStyle}"/>
                        </ObjectAnimationUsingKeyFrames>-->
 
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemDetail" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemListView" Storyboard.TargetProperty="Margin">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="100,0,90,60"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
 
                <!--
                    When an item is selected in portrait the details display requires more extensive changes:
                     * Hide the master list and the column is was in
                     * Move item details down a row to make room for the title
                     * Move the title directly above the details
                     * Adjust margins and padding for details
                 -->
                <VisualState x:Name="FullScreenPortrait_Detail">
                    <Storyboard>
                        <!--<ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PortraitBackButtonStyle}"/>
                        </ObjectAnimationUsingKeyFrames>-->
 
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="primaryColumn" Storyboard.TargetProperty="Width">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemListScrollViewer" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemDetail" Storyboard.TargetProperty="(Grid.Row)">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="1"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemDetail" Storyboard.TargetProperty="(Grid.RowSpan)">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="1"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="titlePanel" Storyboard.TargetProperty="(Grid.Column)">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="1"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemDetailGrid" Storyboard.TargetProperty="Margin">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0,0,0,60"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemDetail" Storyboard.TargetProperty="Padding">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="100,0,90,0"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
 
                <!--
                    The back button and title have different styles when snapped, and the page
                    initially hides details to show only the list of items
                -->
                <VisualState x:Name="Snapped">
                    <Storyboard>
                        <!--<ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedBackButtonStyle}"/>
                        </ObjectAnimationUsingKeyFrames>-->
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="pageTitle" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedPageHeaderTextStyle}"/>
                        </ObjectAnimationUsingKeyFrames>
 
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="primaryColumn" Storyboard.TargetProperty="Width">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="320"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemDetail" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemListView" Storyboard.TargetProperty="ItemTemplate">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource NarrowListItemTemplate}"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemListView" Storyboard.TargetProperty="Margin">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="20,0,0,0"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
 
                <!--
                    When snapped and an item is selected the details display requires more extensive changes:
                     * Hide the master list and the column is was in
                     * Move item details down a row to make room for the title
                     * Move the title directly above the details
                     * Adjust margins and padding for details
                     * Use a different font for title and subtitle
                     * Adjust margins below subtitle
                 -->
                <VisualState x:Name="Snapped_Detail">
                    <Storyboard>
                        <!--<ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedBackButtonStyle}"/>
                        </ObjectAnimationUsingKeyFrames>-->
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="pageTitle" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedPageHeaderTextStyle}"/>
                        </ObjectAnimationUsingKeyFrames>
 
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="primaryColumn" Storyboard.TargetProperty="Width">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemListScrollViewer" Storyboard.TargetProperty="Visibility">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemDetail" Storyboard.TargetProperty="(Grid.Row)">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="1"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemDetail" Storyboard.TargetProperty="(Grid.RowSpan)">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="1"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="titlePanel" Storyboard.TargetProperty="(Grid.Column)">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="1"/>
                        </ObjectAnimationUsingKeyFrames>
                        <!--<ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemDetailTitlePanel" Storyboard.TargetProperty="(Grid.Row)">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemDetailTitlePanel" Storyboard.TargetProperty="(Grid.Column)">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0"/>
                        </ObjectAnimationUsingKeyFrames>-->
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemDetail" Storyboard.TargetProperty="Padding">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="20,0,20,0"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemDetailGrid" Storyboard.TargetProperty="Margin">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0,0,0,60"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemTitle" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TitleTextStyle}"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemTitle" Storyboard.TargetProperty="Margin">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="0"/>
                        </ObjectAnimationUsingKeyFrames>
                        <!--<ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemSubtitle" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource CaptionTextStyle}"/>
                        </ObjectAnimationUsingKeyFrames>-->
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

Tra i vari stati notate come sia presente quello che si occupa di gestire lo snap. In questo esempio l'esecuzione in snap è semplificata perché l'app non implementa una struttura a navigazione, per cui verrà mostrato un elenco di post e basta. Nell'esempio fornito con la documentazione, più completo e complesso, l'app risponde al click sull'elemento mostrando il contenuto e attivando un pulsante back per tornare all'elenco post, sempre in modalità snap. In questi stati visuali si fa riferimento a due template per i controlli, uno chiamato DefaultListItemTemplate e uno NarrowListItemTemplate, ognuno dei quali da utilizzare a seconda dello stato visuale corrente. Eccoli, da inserire nelle risorse:

        <SolidColorBrush x:Key="BlockBackgroundBrush" Color="#FF557EB9"/>
        <!-- Used in Filled and Snapped views -->
        <DataTemplate x:Key="NarrowListItemTemplate">
            <Grid Height="80">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Border Background="{StaticResource BlockBackgroundBrush}" Width="80" Height="80"/>
                <ContentControl Template="{StaticResource DateBlockTemplate}" Margin="-12,-12,0,0"/>
                <StackPanel Grid.Column="1" HorizontalAlignment="Left" Margin="12,8,0,0">
                    <TextBlock Text="{Binding Title}" MaxHeight="56" Foreground="White" TextWrapping="Wrap"/>
                    <TextBlock Text="{Binding Author}" FontSize="12" />
                </StackPanel>
            </Grid>
        </DataTemplate>
 
        <DataTemplate x:Key="DefaultListItemTemplate">
            <Grid HorizontalAlignment="Stretch" Width="Auto" Height="110" Margin="10,10,10,0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <!-- Green date block -->
                <Border Background="{StaticResource BlockBackgroundBrush}" Width="110" Height="110" />
                <ContentControl Template="{StaticResource DateBlockTemplate}" />
                <StackPanel Grid.Column="1"  HorizontalAlignment="Left" Margin="12,8,0,0">
                    <TextBlock Text="{Binding Title}" FontSize="26.667" TextWrapping="Wrap"
                           MaxHeight="72" Foreground="White" />
                    <TextBlock Text="{Binding Author}" FontSize="18.667" />
                </StackPanel>
            </Grid>
        </DataTemplate>

Si fa riferimento ad un template chiamato DateBlockTemplate, che consente di formattare la data di pubblicazione del post in un modo simile a quello che avete visto nella figura precedente, che poi è ripreso dalla documentazione con qualche modifica. Tale template va in App.xaml per renderlo potenzialmente riutilizzabile:

        <ControlTemplate x:Key="DateBlockTemplate">
            <Canvas Height="86" Width="86"  Margin="8,8,0,8" HorizontalAlignment="Left" VerticalAlignment="Top">
                <TextBlock TextTrimming="WordEllipsis" TextWrapping="NoWrap" 
                     Width="Auto" Height="Auto" Margin="8,0,4,0" FontSize="32" FontWeight="Bold">
                          <TextBlock.Text>
                              <Binding Path="PubDate" Converter="{StaticResource dateConverter}" ConverterParameter="month"  />
                          </TextBlock.Text>
                </TextBlock>
 
                <TextBlock TextTrimming="WordEllipsis" TextWrapping="Wrap" 
                     Width="40" Height="Auto" Margin="8,0,0,0" FontSize="34" FontWeight="Bold" Canvas.Top="36">
                        <TextBlock.Text>
                            <Binding Path="PubDate" Converter="{StaticResource dateConverter}" ConverterParameter="day"  />
                        </TextBlock.Text>
                </TextBlock>
                <Line Stroke="White" StrokeThickness="2" X1="54" Y1="46" X2="54" Y2="80" />
 
                <TextBlock TextWrapping="Wrap" 
                     Width="20" Height="Auto" FontSize="{StaticResource ContentFontSize}" Canvas.Top="42" Canvas.Left="60">
                        <TextBlock.Text>
                            <Binding Path="PubDate" Converter="{StaticResource dateConverter}" ConverterParameter="year"  />
                        </TextBlock.Text>
                </TextBlock>
            </Canvas>
        </ControlTemplate>

A questo punto dobbiamo fare due cose: modificare la UI affinché sia in grado di essere più gradevole e adattabile agli stati e fare qualche considerazione sulla gestione degli stati a runtime.

Come ti stravolgo la User Interface

Uno dei punti cardine nella documentazione sopra citata è un paragrafo chiamato Creating a consistent look with styles. Useremo il codice mostrato lì per fare molte modifiche. Sostanzialmente definiremo una nuova UI per la pagina principale in questo modo:

  • testo per il nome del contenuto visualizzato
  • uno ScrollViewer con ListView, che mostra l'elenco dei post secondo i due template precedentemente definiti
  • uno ScrollViewer con controllo WebView per la visualizzazione dell'anteprima
  • lasceremo invariata l'app bar e le sue funzionalità

Devo, per forza di cose, dare per scontato che abbiate dimestichezza con XAML. Il codice non è complicato, lo è riassumere codice lungo e dettagliate spiegazioni. Lo XAML da inserire all'interno della Grid radice è il seguente:

        <!--
        This grid acts as a root panel for the page that defines two rows:
        * Row 0 contains the back button and page title
        * Row 1 contains the rest of the page layout
    -->
        <Grid Background="{StaticResource ApplicationPageBackgroundBrush}">
            <Grid.RowDefinitions>
                <RowDefinition Height="140"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition x:Name="primaryColumn" Width="610"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
 
            <!-- Back button and page title -->
            <Grid x:Name="titlePanel" Grid.ColumnSpan="2">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
 
                <TextBlock x:Name="pageTitle" Grid.Column="1" Text="{Binding Feed.Title}" Style="{StaticResource GridTitleTextStyle}"/>
            </Grid>
 
            <!-- Vertical scrolling item list -->
            <ScrollViewer
            x:Name="itemListScrollViewer"
            AutomationProperties.AutomationId="ItemListScrollViewer"
            Grid.Row="1"
            Margin="-10,-10,0,0"
            Style="{StaticResource VerticalScrollViewerStyle}">
 
                <ListView
                x:Name="itemListView"
                AutomationProperties.AutomationId="ItemsListView"
                AutomationProperties.Name="Items"
                Margin="120,0,0,60"
                ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
                SelectionChanged="ItemListView_SelectionChanged"
                ItemTemplate="{StaticResource DefaultListItemTemplate}"/>
 
            </ScrollViewer>
 
            <ScrollViewer
            x:Name="itemDetail"
            AutomationProperties.AutomationId="ItemDetailScrollViewer"
            Grid.Column="1"
            Grid.Row="1"
            Padding="70,0,120,0"
            DataContext="{Binding SelectedItem, ElementName=itemListView}"
            Style="{StaticResource VerticalScrollViewerStyle}">
 
                <Grid x:Name="itemDetailGrid">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
 
                    <TextBlock x:Name="itemTitle" Text="{Binding Title}" 
                           Style="{StaticResource SubheaderTextStyle}">
                      <TextBlock.Transitions>
                        <TransitionCollection>
                            <ContentThemeTransition />
                        </TransitionCollection>
                      </TextBlock.Transitions>
 
                    </TextBlock>
                    <Border x:Name="contentViewBorder" BorderBrush="Gray" BorderThickness="2" 
                        Grid.Row="1" Margin="0,15,0,20">
                        <Grid>
                            <WebView x:Name="contentView" />
                            <Rectangle x:Name="contentViewRect" />
                        </Grid>
                    </Border>
                </Grid>
            </ScrollViewer>

Apparirà ora più chiaro come le varie fasi degli stati visuali influenzino controlli specifici, che ora vediamo nel codice con il loro nome. Si noti come alcuni controlli siano in binding con le proprietà di interesse della classe FeedItem la cui istanza costituisce la fonte dati della pagina. Infine si noti come il template assegnato in via prioritaria sia quello chiamato DefaultListItemTemplate. Questo cambierà a seconda dello stato visuale. Il controllo e la gestione degli stati è poi responsabilità del runtime.

Gli stati visuali a runtime

La classe LayoutAwarePage implementa di default tutto ciò che è necessario per gestire gli stati visuali a runtime, oltre all'infrastruttura per la navigazione. Nel nostro semplice esempio siamo fortunati perché non abbiamo necessità di fare altro, ma se la nostra app è composta da più pagine è necessario fare l'override di alcuni metodi e gestire il comportamento degli stati in fase di navigazione.

La documentazione offre tutto ciò che è necessario sapere per implementare correttamente queste caratteristiche.

Test

Potete ora divertirvi a testare l'app ruotando il simulatore, soprattutto capire il discorso dello snap. Il codice aggiornato è disponibile a questo indirizzo.

Alessandro

Print | posted on mercoledì 16 maggio 2012 00:14 | Filed Under [ Visual Basic UWP e Windows Store Apps Visual Studio 2012 ]

Powered by:
Powered By Subtext Powered By ASP.NET