YouTube Search App #3
Dieser Artikel ist ein Gastbeitrag von Tobias Oliver, Informatik-Student in Karlsruhe und begeisterter App-Entwickler. In diesem Artikel soll es um die XML-Verarbeitung (Atom) gehen. Allerdings an einem spannenden Beispiel, nicht dem alt-bekannten RSS-Reader. Wir holen uns einen Video-Feed von YouTube, stellen ihn hübsch dar und wollen am Ende natürlich das Video sehen.
Dieses mal wollen wir unserer YouTube-App ein schöneres Design verpassen und die Video-Seite implementieren.
Den Hintergrund der App kann man ganz einfach im „Object Inspector“ konfigurieren. Im Normalfall findet man ihn auf der rechten Seite in Visual Studio. Einfach das oberste Grid auswählen und unter „Pinsel“ den gewünschten Hintergrund einstellen. Das geht natürlich auch direkt im XAML-Code. Wir wählen uns einen schlichten Farbverlauf.
Um noch einen Titel anzuzeigen, erstellen wir 2 Zeilen im Grid mit:
1 2 3 4 |
<Grid.RowDefinitions> <RowDefinition Height="140"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> |
Anschließend den folgenden TextBlock:
1 |
<TextBlock Margin="120,0,0,40" Text="YouTube Search App" Style="{StaticResource PageHeaderTextStyle}" /> |
Das bereits vorhandene GridView schieben wir in Grid.Row="1" und mit SelectionMode="None" verhindert man, dass ein Element ausgewählt werden kann.
Per Default sieht das GridView nicht wirklich schön aus und bei scrollen läuft es auch nicht flüssig.
Um das zu lösen, möchte ich einen kleinen Trick zeigen. Wenn man das ItemsPanel vom GridView verändert und ein VariableSizedWrapGrid einstellt, kann man das Problem mit dem rechten Rand lösen und beim scrollen gibt es eine flüssige Animation anstatt dem ruckeln. Das geht so:
1 2 3 4 5 |
<GridView.ItemsPanel> <ItemsPanelTemplate> <VariableSizedWrapGrid Orientation="Vertical" Margin="0,0,80,0"/> </ItemsPanelTemplate> </GridView.ItemsPanel> |
Nun erstellen wir ein eigenes ItemTemplate für die Video-Kacheln. Das geht sehr bequem mit einem Rechtsklick auf das GridView – „Zusätzliche Vorlagen bearbeiten“ – „Generierte Elemente bearbeiten (ItemTemplate)“ – Kopie bearbeiten… – als Name „YoutubeDataTemplate – Dieses Dokument auswählen und OK.
Das erzeugte Template erweitern wir nun um einen Like / Dislike – Indikator. Die Werte dazu haben wir bereits in unserem Model erzeugt mit „RelativeLikes“ und „RelativeDislikes“:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<DataTemplate x:Key="YoutubeDataTemplate"> <Grid HorizontalAlignment="Left" Width="250" Height="250"> <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}"> <Image Source="{Binding Image}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/> </Border> <StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}"> <StackPanel Orientation="Horizontal"> <Rectangle Fill="Green" Height="4" Width="{Binding RelativeLikes}"/> <Rectangle Fill="Red" Height="4" Width="{Binding RelativeDislikes}" /> </StackPanel> <TextBlock Text="{Binding Title}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="40" Margin="15,0,15,0"/> <TextBlock Text="{Binding Subtitle}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/> </StackPanel> </Grid> </DataTemplate> |
Das Ergebnis kann sich schon sehen lassen:
Kommen wir zur Anzeige von Videos. Dazu erstellen wir eine neue „Leere Seite“ und nennen Sie „VideoPage.xaml“. Die grundlegende Struktur und den Hintergrund übernehmen wir einfach von unserer „MainPage“. Auf dieser Seite benötigen wir allerdings einen „BackButton“ um auf die vorherige Seite zurückzukehren. Um dem Style-Guide zu folgen, am besten so:
1 2 3 4 5 6 7 8 9 |
<Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <Button x:Name="backButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/> <TextBlock x:Name="pageTitle" Margin="0,0,0,65" Text="{Binding Title}" Grid.Column="1" IsHitTestVisible="false" Style="{StaticResource PageHeaderTextStyle}"/> <TextBlock x:Name="subTitle" Text="{Binding Subtitle}" Grid.Column="1" IsHitTestVisible="false" FontSize="16" Style="{StaticResource PageHeaderTextStyle}"/> </Grid> |
Den Inhalt der Video-Seite können wir größtenteils per Datenbindung aus unserem YoutubeDataItem übernehmen. Dazu müssen wir dieses beim navigieren übergeben. Also zurück zur MainPage.xaml.
Um ein Element im GridView anzuklicken muss IsItemClickEnabled="True" gesetzt werden, und dann fügen wir einen Ereignishandler für das ItemClick-Event hinzu, z.B. mit ItemClick="GridViewItemClick" und im Code-Behind implementieren wir den Übergang zur „VideoPage“.
Wir lassen den aktuellen Frame einfach zu einer VideoPage navigieren und übergeben das ClickedItem des GridView als Parameter:
1 2 3 4 |
private void GridViewItemClick(object sender, ItemClickEventArgs e) { this.Frame.Navigate(typeof(VideoPage), e.ClickedItem); } |
Und nach dem navigieren auf die VideoPage müssen wir das Item dort als DataContext setzen:
1 2 3 4 |
protected override void OnNavigatedTo(NavigationEventArgs e) { this.DataContext = (YoutubeDataItem)e.Parameter; } |
Und das GoBack vom BackButton wird einfach mit this.Frame.GoBack(); gefüllt.
Den Rest können wir nun komplett im XAML erledigen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<Grid Grid.Row="1" Margin="120,20,65,80"> <Grid.ColumnDefinitions> <ColumnDefinition Width="80*"/> <ColumnDefinition Width="20*"/> </Grid.ColumnDefinitions> <WebView Source="{Binding Source}" /> <Grid Grid.Column="1" Margin="10,0,0,0"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Rectangle Fill="LightGreen" Margin="0,0,0,10" Height="60" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> <StackPanel Orientation="Horizontal" Margin="10"> <TextBlock FontSize="26" Text="?" FontFamily="Segoe UI Symbol" FontWeight="Light" /> <TextBlock FontSize="26" Margin="10,0,0,0" Text="{Binding Likes}" /> </StackPanel> <Rectangle Fill="LightCoral" Margin="0,0,0,10" Height="60" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> <StackPanel Orientation="Horizontal" Grid.Row="1" Margin="10"> <TextBlock FontSize="26" Text="?" FontFamily="Segoe UI Symbol" FontWeight="Light" /> <TextBlock FontSize="26" Margin="10,0,0,0" Text="{Binding Dislikes}" /> </StackPanel> <Rectangle Fill="LightGray" Margin="0,0,0,10" Height="60" Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> <StackPanel Orientation="Horizontal" Grid.Row="2" Margin="10"> <TextBlock FontSize="26" Text="?" FontFamily="Segoe UI Symbol" FontWeight="Light" /> <TextBlock FontSize="26" Margin="10,0,0,0" Text="{Binding Views}" /> </StackPanel> <Rectangle Fill="LightGray" Grid.Row="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" /> <ScrollViewer Grid.Row="3" Margin="10"> <TextBlock Text="{Binding Description}" FontSize="22" TextWrapping="Wrap" /> </ScrollViewer> </Grid> </Grid> |
Fertig ist die VideoPage. So sieht das Resultat aus:
Auch dieses mal, gibt es natürlich den bisherigen Quellcode zum Download:
YouTube-Search #2 (26,1 KiB)