Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Piszemy dla Metro - DP Feeds cz. 1

Chciałbym w moim pierwszym wpisie mojego bloga na DP zaprezentować wam w jaki sposób pisze się aplikacje dla interfejsu Metro, który zadebiutuje wraz z pojawieniem się w 2012 roku nowego systemu operacyjnego firmy Microsoft o kodowej nazwie "Windows 8".

Pokażę wam jak stworzyć czytnik RSS wiadomości z portalu DobreProgramy, oparty o nowy interfejs Metro.
Aby rozpocząć przygodę z pisaniem aplikacji dla Windows 8 należy pobrać udostępnioną publicznie we wrześniu wersję Windows Developer Preview nowego systemu operacyjnego wraz z potrzebnymi narzędziami. Wszystko co trzeba znajdziecie tutaj: Windows 8 Developer Preview with developer tools English, 64-bit (x64)Windows 8 Developer Preview with developer tools English, 64-bit (x64) zawiera wczesną wersję systemu Windows 8 wraz z narzędziem Visual Studio 11, które umożliwi nam dalszą zabawę.

A więc zaczynamy.

Uruchamiamy edytor Visual Studio i wybieramy "New Project"

Następnie wybieramy typ "Application" oraz wpisujemy nazwę naszego programu (DP Feeds) w polu "Name:"
Visual Studio utworzyło nam odpowiedni szablon aplikacji, nie będę tutaj wnikał w konstrukcję samego szablonu, po odpowiednie info zapraszam na MSDN

Obecnie okno Visual Studio powinno wyglądać tak:

Narazie będzie interesować nas kod XAML oraz sam edytor wizualny ponieważ w tej części stworzymy sobie forme (stronę - jak ja to nazywam) aplikacji ze wszystkimi komponentami które będą później wypełnione odpowiednimi danymi.
Nasze okno będzie składać się z nagłówka, lewej części w której będą wyświetlane bieżące tytuły newsów oraz daty publikacji na DP, po prawej stronie znajdzie się skrót treści wybranego wpisu. Klikając odpowiedni przycisk będzie można przejść do następnej "strony" naszej aplikacji, gdzie będzie wyświetlone okno przedstawiające całość newsa już w kontrolce WebView.

Kodujemy

Na wstępie zmienimy sobie typ okna głównego (strony) z "UserControl" na "Page" co uprości nam nawigację pomiędzy poszczególnymi stronami naszej aplikacji. Ja akurat preferuję taki sposób, potem wyjaśnię troszkę w czym rzecz gdy będziemy budowali drugą stronę programu na której znajdzie się mini przeglądarka w której będzie można obejrzeć cały, wybrany news z DP łącznie z komentarzami.

Zmiany dokonujemy w następujący sposób: w edytorze XAML zmieniamy wpis:

<UserControl x:Class="DP_Feeds_X.MainPage" .................. .................. </UserControl>

na

<Page x:Class="DP_Feeds_X.MainPage" .................. .................. </Page>

Następnym krokiem będzie zdefiniowanie stylu czcionki nagłówka naszej strony głównej aplikacji oraz samego stylu nagłówka. W tym celu pod linijką:

d:DesignHeight="768" d:DesignWidth="1366">

umieszczamy następujący kod:

<UserControl.Resources> <SolidColorBrush x:Key="HighlightBrush" Color="#FF26A0DA"/> <Style x:Key="DefaultFontStyle" TargetType="TextBlock"> <Setter Property="Foreground" Value="White"/> <Setter Property="FontSize" Value="26.667"/> <Setter Property="FontFamily" Value="Segoe UI"/> <Setter Property="FontWeight" Value="Light"/> <Setter Property="Margin" Value="0,0,0,0"/> <Setter Property="TextTrimming" Value="WordEllipsis"/> <Setter Property="TextWrapping" Value="Wrap"/> </Style> <Style x:Key="PageTitleStyle" TargetType="TextBlock" BasedOn="{StaticResource DefaultFontStyle}"> <Setter Property="Margin" Value="40,0,40,28" /> <Setter Property="VerticalAlignment" Value="Bottom" /> <Setter Property="TextWrapping" Value="NoWrap"/> <Setter Property="FontSize" Value="53.333"/> </Style> </UserControl.Resources>

W powyższym przykładzie zdefiniowaliśmy sam styl naszego nagłówka, nie został on jeszcze jednak umieszczony na naszej "stronie" aplikacji i żadne zmiany nie są widoczne. Obecnie "strona" aplikacji jest czarna i nie znajdują się na niej żadne komponenty. Aby je tam umieścić wstawiamy odpowiedni kod pomiędzy linie:

<Grid x:Name="LayoutRoot" Background="#FF0C0C0C"> </Grid>

Wstępnie oddzielimy nasz nagłówek od reszty strony linią siatki. Aby to zrobić, pomiędzy powyższymi liniami umieszczamy kod:

<Grid.RowDefinitions> <RowDefinition Height="140"/> <RowDefinition Height="*"/> </Grid.RowDefinitions>

następnie pod tym kodem umieszczamy kod komponentu "TextBlock", który uwidoczni nasz nagłówek na "stronie" naszej aplikacji:

<Grid> <TextBlock x:Name="PageTitle" Text="DobreProgramy.pl" Style="{StaticResource PageTitleStyle}" Grid.Column="1" /> </Grid>

Cały nasz kod XAML "strony" powinien teraz wyglądać tak:

W polu Style="{StaticResource PageTitleStyle}" wskazaliśmy odnośnik do stylu czcionki oraz nagłówka, który zdefiniowaliśmy sobie na początku.

Tworzymy klasy

Zajmiemy się teraz stworzeniem odpowiednich klas oraz kodem który pobierze dla nas odpowiednie dane z kanału RSS strony DobreProgramy.pl

Przechodzimy zatem do kodu C# naszej strony, aby to zrobić rozwijamy gałąź MainPage.xaml która znajduje się w oknie Solution Explorer-a po prawej stronie okna głównego VS, następnie dwukrotnie klikamy na plik MainPage.xaml.cs. W tym momencie naszym oczom ukaże się edytor kodu źródłowego C# naszej strony.

Najpierw dodamy sobie dwie klasy:

public class FeedData { public string Title { get; set; } //using System.Collections.ObjectModel; private ObservableCollection<FeedItem> _Items = new ObservableCollection<FeedItem>(); public ObservableCollection<FeedItem> Items { get { return this._Items; } } } public class FeedItem { public string Title { get; set; } public string Content { get; set; } public DateTime PubDate { get; set; } public string Url { get; set; } }

Pamiętamy oczywiście o deklaracji System.Collections.ObjectModel który definiuje klasę ObservableCollection<T>.

Następnym krokiem jest dodanie funkcji która będzie wczytywać dane ze strumienia RSS portalu DobreProgramy, najpierw deklarujemy Windows.Web.Syndication następnie dodajemy funkcję GetFeedAsync(string feedUriString):

private async Task GetFeedAsync(string feedUriString) { // using Windows.Web.Syndication; SyndicationClient client = new SyndicationClient(); Uri feedUri = new Uri(feedUriString); try { SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri); FeedData feedData = new FeedData(); feedData.Title = feed.Title.Text; foreach (SyndicationItem item in feed.Items) { FeedItem feedItem = new FeedItem(); feedItem.Title = item.Title.Text; feedItem.PubDate = item.PublishedDate.DateTime; feedItem.Author = item.Authors[0].Name.ToString(); feedItem.Url = item.Links[0].Uri.ToString(); if (feed.SourceFormat == SyndicationFormat.Atom10) { feedItem.Content = item.Content.Text; } else if (feed.SourceFormat == SyndicationFormat.Rss20) { feedItem.Content = item.Summary.Text; } feedData.Items.Add(feedItem); DateTime date = feedItem.PubDate; string _title = item.Title.Text; string _tags = item.Authors[0].Name.ToString(); } this.DataContext = feedData; ItemListView.SelectedIndex = 0; } catch { // Log Error. } }

Do funkcji jako feedUriString przekazujemy adres kanału RSS ("http://feeds.feedburner.com/dobreprogramy/Aktualnosci") a samo jej wykonanie deklarujemy zaraz po funkcji inicjalizacji komponentów.
Kod naszego głównej strony programu powinien teraz wyglądać tak:

using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Data; using Windows.Web.Syndication; namespace DP_Feeds_Ex { partial class MainPage { public MainPage() { InitializeComponent(); GetFeedAsync("http://feeds.feedburner.com" +"/dobreprogramy/Aktualnosci"); } private async Task GetFeedAsync(string feedUriString) { // using Windows.Web.Syndication; SyndicationClient client = new SyndicationClient(); Uri feedUri = new Uri(feedUriString); try { SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri); FeedData feedData = new FeedData(); feedData.Title = feed.Title.Text; foreach (SyndicationItem item in feed.Items) { FeedItem feedItem = new FeedItem(); feedItem.Title = item.Title.Text; feedItem.PubDate = item.PublishedDate.DateTime; feedItem.Author = item.Authors[0].Name.ToString(); feedItem.Url = item.Links[0].Uri.ToString(); if (feed.SourceFormat == SyndicationFormat.Atom10) { feedItem.Content = item.Content.Text; } else if (feed.SourceFormat == SyndicationFormat.Rss20) { feedItem.Content = item.Summary.Text; } feedData.Items.Add(feedItem); DateTime date = feedItem.PubDate; string _title = item.Title.Text; string _tags = item.Authors[0].Name.ToString(); } this.DataContext = feedData; ItemListView.SelectedIndex = 0; } catch { // Log Error. } } } public class FeedData { public string Title { get; set; } //using System.Collections.ObjectModel; private ObservableCollection<FeedItem> _Items = new ObservableCollection<FeedItem>(); public ObservableCollection<FeedItem> Items { get { return this._Items; } } } public class FeedItem { public string Title { get; set; } public string Author { get; set; } public string Content { get; set; } public DateTime PubDate { get; set; } public string Url { get; set; } } }

Wyświetlamy nasze dane

Wróćmy teraz do kodu XAML budującego nasz interfejs "strony" głównej programu.
Zabawę z tworzeniem interfejsu zakończyliśmy na stworzeniu nagłówka i oddzieleniu do od reszty "strony", czas aby dodać odpowiednią kontrolki które wyświetli (pobierze) dane z naszej dynamicznej kolekcji danych Items którą zadeklarowaliśmy w klasie FeedData i wypełniliśmy danymi newsów uzyskanymi z kanału RSS portalu DobreProgramy.

W tym celu w edytorze XAML naszej strony umieścimy kod komponentu ListView który będzie wyświetlał tytuły newsów na stronie, wraz z datą publikacji:

<!-- Lewa kolumna --> <ListView x:Name="ItemListView" ItemsSource="{Binding Path=Items}" Margin="8,0,0,10"> <ListView.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="{Binding Path=Title}" FontSize="24" Margin="5,0,0,0" TextWrapping="Wrap" /> <TextBlock Text="{Binding Path=PubDate}" FontSize="16" Margin="15,0,0,0"/> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView>

A także kod komponentu który wyświetli skrót (początek) newsa oraz pełny nagłówek:

<!-- Prawa kolumna --> <Grid DataContext="{Binding ElementName=ItemListView, Path=SelectedItem}" Grid.Column="1" Margin="25,8,0,-8"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <TextBlock Text="{Binding Path=Title}" FontSize="26" FontFamily="Segoe UI"/> <WebView x:Name="ContentView" Grid.Row="1" Margin="0,5,20,738" Opacity="0.5"/> </Grid>

Następnie dodajemy zdarzenie w kodzie naszego programu, które będzie wyświetlać fragment newsa po jego wybraniu z listy po lewej stronie.
W tym celu, w edytorze "Design" naszej strony, dwukrotnie klikamy na pustą kontrolkę ListView (znajduje się ona z lewej strony):

Visual Studio wygeneruje odpowiedni kod zdarzenia, który uzupełnimy wpisem:

FeedItem feedItem = (sender as ListView).SelectedItem as FeedItem; if (feedItem != null) { ContentView.NavigateToString("<html><body bgcolor=\"#121212\"><font color=\"white\">" + feedItem.Content + "</font></body></html>"); }

I oto nasza wstępnie działająca aplikacja:

Życzę miłej zabawy :)

W następnej części dowiemy się jak stworzyć koleją "stronę" dla naszej aplikacji, troszkę o nawigowaniu między stronami oraz przekazywaniu pomiędzy nimi argumentów :)

Pełny kod źródłowy dostępny tutaj: http://www5.zippyshare.com/v/11483393/file.html 

windows oprogramowanie programowanie

Komentarze

0 nowych
underface   14 #1 23.12.2011 13:10

powstanie prawie oficjalna aplikacja DP na smartfony z windowsem
ciekawe czy ktos zabierze sie za cos takiego na androida i iOS'a

SunriSebi   4 #2 23.12.2011 13:15

Mam nadzieję że powstaną fajne pomysły na dodatkowe opcje takiej aplikacji :)

Caffreys   2 #3 23.12.2011 14:06

Bardzo ciekawe, i przede wszystkim każdy sam może spróbować.

SunriSebi   4 #4 23.12.2011 14:37

Nie dość że spróbować to jeszcze obczaić o co w tym całym programowaniu pod Metro chodzi. Na większą uwagę zasługuje tutaj nowa klasa SyndicationClient http://msdn.microsoft.com/en-us/library/windows/apps/windows.web.syndication.syn... do obsługi Feeds. A także klasy pomocnicze :)

Malkolm   3 #5 23.12.2011 16:49

Dzięki za ten wpis. Może on niektórym fanboy-om Linuksa choć trochę poszerzy horyzonty i pomoże odnaleźć się w świecie zamkniętego oprogramowania.

Mantarak   3 #6 23.12.2011 19:24

Bardzo fajny merytoryczny wpis. Może w swiątecznym wolnym czasie spróbuję.
Zachęcam innych do tworzenia podobnych wpisów a nie tylko o wyższości systemu czy przeglądarki x nad y.

ludendorf   6 #7 23.12.2011 21:05

@underface
Mam nadzieję że o badaOS nie zapomną !

dominikc   5 #8 23.12.2011 21:08

@ludenorf
Już na iOS jest, czeka na akceptację u moderatora:)

  #9 24.12.2011 00:35

Czyli na 8 też możemy się spodziewać Sunrise Seven?

SunriSebi   4 #10 24.12.2011 09:49

@bartek46op
Oczywiście :) Tylko raczej nie pod Metro ze względu na ograniczenia API

tux35   6 #11 24.12.2011 15:07

Jak przeczytałem tytuł to myślałem o Metro jako gazecie :D

SunriSebi   4 #12 25.12.2011 09:55

xD

DawidDS4   5 #13 25.12.2011 10:49

Też jestem za BadaOS!