Monday 16 February 2015

Rss Feed Complete Code

Objectives

In this blog, we take a quick tour of the features that you'll use to build Windows Store apps. Through the process of creating a simple blog reader app, we introduce concepts that are core to development with XAML, including layout, controls, templates, and data binding. You learn how to use the page templates and navigation that are built into Microsoft Visual Studio Express 2012 for Windows 8 to quickly start your app development. You then learn how to use custom styles to modify the look of the app, and how to adapt the UI to various layouts and views. Finally, we briefly discuss integrating the app with Windows 8 and publishing it to the Windows Store. By the time you complete this tutorial, you'll be prepared to start building your own Windows Store apps.

When you create your Windows Store app using C# or Visual Basic, you typically define the UI using XAML, and write your app logic in an associated code behind file in your selected language. The XAML UI framework for Windows Store apps using C# or Visual Basic is in the Windows.UI.Xaml.* namespaces of the Windows Runtime. If you've written apps using Windows Presentation Foundation (WPF), Microsoft Silverlight, or Silverlight for Windows Phone, you're already familiar with this programming model and you can use this experience to create your Windows Store app using C# or Visual Basic.
The example here shows the XAML that defines the UI for a simple "Hello, world" app and its associated code behind page. Even this simple example shows several concepts that are important to the XAML-based programming model, including partial classes, layout, controls, properties, and events.
XAML
<Page
x:Class="WindowsBlogReader.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:WindowsBlogReader"
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">
<TextBlock x:Name="DisplayText" FontSize="48" />
<StackPanel> <Button Content="Click Me" Click="HelloButton_Click" /> </StackPanel>
</Grid>
</Page>
C#
VB
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace WindowsBlogReader {
public sealed partial class MainPage : Page
{ public MainPage() { InitializeComponent();
private void HelloButton_Click(object sender, RoutedEventArgs e)
} { DisplayText.Text = "Hello, world"; } } }
A "Hello, world" app is good place to start. But it doesn't take you very far down the road to profitability, so we'll take a different path as we explore building Windows Store apps. The sample app that you use to get started is a simple blog reader that downloads and displays data from a Really Simple Syndication (RSS) 2.0 or Atom 1.0 feed. It seems appropriate to use the feeds from the Windows team blogs site. When you're done, the app looks like this.
Three-page navigation example.

Creating Windows Store apps in Visual Studio

In this section, you will learn how to:
  • create a new Windows Store app project in Visual Studio Express 2012 for Windows 8.
Visual Studio is a powerful Integrated Development Environment (IDE) for developing Windows apps. It provides source file management; integrated build, deployment and launching support; XAML, Visual Basic, C#, C++, graphics, and manifest editing; debugging, and more. Visual Studio comes in several editions, but you'll use Visual Studio Express 2012 for Windows 8. You can download it for free along with the Windows Software Development Kit (SDK) for Windows 8 so that you have everything you need to build, package and deploy your Windows Store apps.
To get started creating an app, you create a new Windows Store project using C# or Visual Basic. Visual Studio Express 2012 for Windows 8 includes several templates for Windows Store projects that give you a head start on apps using a variety of layouts. The Blank App (XAML) project template provides the minimum files you need for any Windows Store app.
For more info about Visual Studio Express 2012 for Windows 8, see Develop Windows Store apps using Visual Studio 2012.
BR211380.wedge(en-us,WIN.10).gifTo create a new Windows Store project
  1. Open Visual Studio Express 2012 for Windows 8.
  2. Select File > New Project. The New Project dialog opens.
  3. Under Templates in the left pane, expand Visual C# or Visual Basic.
  4. Select the Windows Store template type.
  5. In the center pane, select Blank App (XAML).
  6. Enter a name for the project. Name this project "WindowsBlogReader".
    Here's a new project being created in Visual Studio Express 2012 for Windows 8.
    Visual Studio New Project dialog.
  7. Click OK. Your project files are created.
When you create your project, Visual Studio creates the project files and displays them in Solution Explorer. Let's look at the folders and files that the Blank App (XAML) template creates.
FILE NAMEDESCRIPTION
Properties/AssemblyInfo (.vb or .cs)Contains the name and version metadata that is embedded into the generated assembly.
Package.appxmanifestContains metadata that describes your app, including display name, description, logos, and capabilities.
Assets/*The default logo and splash screen images that you can replace with your own.
Common/StandardStyles.xamlContains default styles and templates for the app.
App.xaml, App.xaml.cs/vbThese files specify app-level logic. The App class is required to display the user interface.
MainPage.xamlThe default start page that you use to create the user interface.
MainPage.xaml.cs/vbThe code-behind file that contains the logic for the default start page.
To learn more about these files and templates, see Templates to speed up your app development.

Getting data into an app

In this section, you will learn how to:
  • create a custom data class
  • retrieve an RSS or Atom data feed asynchronously.
Before you create the UI for the app, you write the code to get the blog feed data so you have something to show in the UI. The Windows team blogs expose the full text of the posts in both RSS and Atom form. The blog data that you want to display in the reader app is the title, author, date, and content from each of the latest blog posts.
To start, you need to download the data for each of the posts. Fortunately, the Windows Runtime contains a set of classes that does a lot of the work of processing the feed data for you. You find these classes in theWindows.Web.Syndication namespace. It’s possible to use these classes directly to show the data in the UI. But in the blog reader, you create your own data classes. This gives you some additional flexibility and allows you to treat RSS and Atom feeds in the same way.
You use 3 classes to hold and retrieve the feed data in the blog reader app. You put all 3 classes in one file named FeedData.cs/vb. The FeedData class holds info about the RSS or Atom feed. The FeedItem class holds info about individual blog posts that the feed contains. The FeedDataSource class contains a collection of feeds and a method to retrieve the feeds from the network.
To add data classes to the project
  1. Select Project > Add Class. The New Item dialog box opens.
  2. Enter "FeedData" as the name for the class file.
  3. Click Add. Your new class file is created.
  4. Copy this code into the FeedData.cs/vb file. Replace any code that is in the file.
    C#
    VB
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using Windows.Web.Syndication;
    using System.Threading.Tasks;
    // Holds info for a single blog feed, including a list of blog posts (FeedItem).
    namespace WindowsBlogReader { // FeedData
    public string Title { get; set; }
    public class FeedData {
    public DateTime PubDate { get; set; }
    public string Description { get; set; }
    public List<FeedItem> Items
    private List<FeedItem> _Items = new List<FeedItem>(); { get {
    // Holds info for a single blog post.
    return this._Items; } } } // FeedItem public class FeedItem {
    public DateTime PubDate { get; set; }
    public string Title { get; set; } public string Author { get; set; } public string Content { get; set; }
    // retreive the feeds.
    public Uri Link { get; set; } } // FeedDataSource // Holds a collection of blog feeds (FeedData), and contains methods needed to
    public ObservableCollection<FeedData> Feeds
    public class FeedDataSource { private ObservableCollection<FeedData> _Feeds = new ObservableCollection<FeedData>(); { get { return this._Feeds; }
    Task<FeedData> feed2 =
    } public async Task GetFeedsAsync() { Task<FeedData> feed1 = GetFeedAsync("http://windowsteamblog.com/windows/b/developers/atom.aspx");
    GetFeedAsync("http://windowsteamblog.com/windows/b/extremewindows/atom.aspx");
    GetFeedAsync("http://windowsteamblog.com/windows/b/windowsexperience/atom.aspx" Task<FeedData> feed3 = Task<FeedData> feed4 = GetFeedAsync("http://windowsteamblog.com/windows/b/business/atom.aspx"); Task<FeedData> feed5 =
    GetFeedAsync("http://windowsteamblog.com/windows/b/springboard/atom.aspx");
    GetFeedAsync("http://windowsteamblog.com/windows/b/bloggingwindows/atom.aspx"); Task<FeedData> feed6 = GetFeedAsync("http://windowsteamblog.com/windows/b/windowssecurity/atom.aspx"); Task<FeedData> feed7 = Task<FeedData> feed8 = GetFeedAsync("http://windowsteamblog.com/windows/b/windowshomeserver/atom.aspx");
    Task<FeedData> feed12 =
    Task<FeedData> feed9 = GetFeedAsync("http://windowsteamblog.com/windows_live/b/windowslive/rss.aspx"); Task<FeedData> feed10 = GetFeedAsync("http://windowsteamblog.com/windows_live/b/developer/atom.aspx"); Task<FeedData> feed11 = GetFeedAsync("http://windowsteamblog.com/ie/b/ie/atom.aspx");
    this.Feeds.Add(await feed2);
    GetFeedAsync("http://windowsteamblog.com/windows_phone/b/wpdev/atom.aspx"); Task<FeedData> feed13 = GetFeedAsync("http://windowsteamblog.com/windows_phone/b/wmdev/atom.aspx"); Task<FeedData> feed14 = GetFeedAsync("http://windowsteamblog.com/windows_phone/b/windowsphone/atom.aspx"); this.Feeds.Add(await feed1); this.Feeds.Add(await feed3);
    this.Feeds.Add(await feed13);
    this.Feeds.Add(await feed4); this.Feeds.Add(await feed5); this.Feeds.Add(await feed6); this.Feeds.Add(await feed7); this.Feeds.Add(await feed8); this.Feeds.Add(await feed9); this.Feeds.Add(await feed10); this.Feeds.Add(await feed11); this.Feeds.Add(await feed12); this.Feeds.Add(await feed14);
    // This code is executed after RetrieveFeedAsync returns the SyndicationFeed.
    } private async Task<FeedData> GetFeedAsync(string feedUriString) { Windows.Web.Syndication.SyndicationClient client = new SyndicationClient(); Uri feedUri = new Uri(feedUriString); try { SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri);
    feedData.Description = feed.Subtitle.Text;
    // Process the feed and copy the data you want into the FeedData and FeedItem classes. FeedData feedData = new FeedData(); if (feed.Title != null && feed.Title.Text != null) { feedData.Title = feed.Title.Text; } if (feed.Subtitle != null && feed.Subtitle.Text != null) { }
    if (item.Title != null && item.Title.Text != null)
    if (feed.Items != null && feed.Items.Count > 0) { // Use the date of the latest post as the last updated date. feedData.PubDate = feed.Items[0].PublishedDate.DateTime; foreach (SyndicationItem item in feed.Items) { FeedItem feedItem = new FeedItem(); { feedItem.Title = item.Title.Text;
    // Handle the differences between RSS and Atom feeds.
    } if (item.PublishedDate != null) { feedItem.PubDate = item.PublishedDate.DateTime; } if (item.Authors != null && item.Authors.Count > 0) { feedItem.Author = item.Authors[0].Name.ToString(); } if (feed.SourceFormat == SyndicationFormat.Atom10)
    else if (feed.SourceFormat == SyndicationFormat.Rss20)
    { if (item.Content != null && item.Content.Text != null) { feedItem.Content = item.Content.Text; } if (item.Id != null) { feedItem.Link = new Uri("http://windowsteamblog.com" + item.Id); } } {
    }
    if (item.Summary != null && item.Summary.Text != null) { feedItem.Content = item.Summary.Text; } if (item.Links != null && item.Links.Count > 0) { feedItem.Link = item.Links[0].Uri; } } feedData.Items.Add(feedItem); } return feedData; }
    // Returns the post that has the specified title.
    catch (Exception) { return null; } } // Returns the feed that has the specified title. public static FeedData GetFeed(string title) { // Simple linear search is acceptable for small data sets var _feedDataSource = App.Current.Resources["feedDataSource"] as FeedDataSource; var matches = _feedDataSource.Feeds.Where((feed) => feed.Title.Equals(title)); if (matches.Count() == 1) return matches.First(); return null; }
    public static FeedItem GetItem(string uniqueId) { // Simple linear search is acceptable for small data sets var _feedDataSource = App.Current.Resources["feedDataSource"] as FeedDataSource; var _feeds = _feedDataSource.Feeds; var matches = _feedDataSource.Feeds.SelectMany(group => group.Items).Where((item) => item.Title.Equals(uniqueId)); if (matches.Count() == 1) return matches.First(); return null; } }
    }
  5. Click Build > Build solution to make sure the solution builds without error.

Retrieving the feed data

Let's take a closer look at how you download the blog feeds. The Windows.Web.Syndication.SyndicationClientclass retrieves a fully parsed RSS or Atom feed, so you can use the data without worrying about parsing XML. To download a feed using the SyndicationClient class, you have to use the asynchronous RetrieveFeedAsyncmethod. The asynchronous programming model is common in the Windows Runtime to help apps remain responsive. Fortunately, much of the complexity you might expect when using asynchronous methods has been taken care of for you.

Using await in C# and Visual Basic

Using the await keyword in C# and Visual Basic, the code for retrieving the feed asynchronously is similar to the code you would use to retrieve the feed synchronously. Let's take a look.
In the GetFeedsAsync method, you call GetFeedAsync for each of the blog feeds you want to retrieve. Where possible, you pass in the URL for the Atom feed because it includes author data that you want to show. If there's no Atom feed, use the RSS feed. When each blog feed is returned, you add it to the FeedDataSource.Feeds collection.
To do this using synchronous methods, your code might look like this. Here, the GetFeed method returns aFeedData object. When the FeedData is returned, it's added to the Feeds collection.
C#
VB
public void GetFeeds()
{
GetFeed("http://windowsteamblog.com/windows/b/developers/atom.aspx");
FeedData feed1 =
this.Feeds.Add(feed1);
... ... }
Now let's look at how you do this using "async" methods, and see how the await keyword helps. The first thing to notice is that you add the async keyword to the method signature. You can use the await keyword only in a method that's defined as async. You specify the return type of GetFeedsAsync as Task.
C#
VB
public async Task GetFeedsAsync()
{ Task<FeedData> feed1 =
GetFeedAsync("http://windowsteamblog.com/windows/b/developers/atom.aspx");
... this.Feeds.Add(await feed1); ... }
In your async code, the GetFeedAsync method returns a Task<FeedData>, or Task(Of FeedData) in VB, that represents the FeedData that will eventually be the return value of the method.
At this point in the code:
C#
VB
this.Feeds.Add(await feed1);
the call to GetFeedAsync is made, and a Task<FeedData> is returned. Then the next line of code is executed (to getfeed2), but feed1 is not added to the Feeds collection until the FeedData object is actually passed to theTask<FeedData> that's waiting for it. We come back to this shortly. Now let's look at what happens in theGetFeedAsync method.
You specify the return type of GetFeedAsync as Task<FeedData>. This tells the compiler to generate a Task that represents the FeedData object that the method retrieves.
C#
VB
private async Task<FeedData> GetFeedAsync(string feedUriString)
{ ... }
Inside the method, you instantiate a SyndicationClient and call its RetrieveFeedAsync method to get theSyndicationFeed that contains the RSS or Atom info that you want.
C#
VB
Windows.Web.Syndication.SyndicationClient client = new SyndicationClient();
Uri feedUri = new Uri(feedUriString); ...
SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri);
Because RetrieveFeedAsync is an asynchronous method, you use the await keyword again. The await keyword tells the compiler to do a lot of work for you behind the scenes. The compiler schedules the rest of the method after this call as a callback to be executed when the call returns. It then immediately returns control to the calling thread, typically the UI thread, so that the app remains responsive. The Task<FeedData> that represents the eventual outcome of this method, a FeedData object, is returned to the caller at this point.
When RetrieveFeedAsync returns the SyndicationFeed with the data you want, the rest of the code in your method is executed. And, importantly, it's executed in the same thread context that you made the original call from (the UI thread), so you don't have to worry about using a dispatcher if you want to update the UI in this code. With the SyndicationFeed retrieved, you copy the parts you need into your FeedData and FeedItem data classes.
C#
VB
// This code is executed after RetrieveFeedAsync returns the SyndicationFeed.
// Process the feed and copy the data you want into the FeedData and FeedItem classes.
FeedData feedData = new FeedData();
feedData.Title = feed.Title.Text;
if (feed.Title != null && feed.Title.Text != null) { }
feedData.Description = feed.Subtitle.Text;
if (feed.Subtitle != null && feed.Subtitle.Text != null) { } if (feed.Items != null && feed.Items.Count > 0) {
feedData.PubDate = feed.Items[0].PublishedDate.DateTime;
// Use the date of the latest post as the last updated date. foreach (SyndicationItem item in feed.Items) { FeedItem feedItem = new FeedItem();
feedItem.PubDate = item.PublishedDate.DateTime;
if (item.Title != null && item.Title.Text != null) { feedItem.Title = item.Title.Text; } if (item.PublishedDate != null) { }
if (feed.SourceFormat == SyndicationFormat.Atom10)
if (item.Authors != null && item.Authors.Count > 0) { feedItem.Author = item.Authors[0].Name.ToString(); } // Handle the differences between RSS and Atom feeds. {
feedItem.Link = new Uri("http://windowsteamblog.com" + item.Id);
if (item.Content != null && item.Content.Text != null) { feedItem.Content = item.Content.Text; } if (item.Id != null) { } }
{
else if (feed.SourceFormat == SyndicationFormat.Rss20) { if (item.Summary != null && item.Summary.Text != null) { feedItem.Content = item.Summary.Text; } if (item.Links != null && item.Links.Count > 0)
feedItem.Link = item.Links[0].Uri; } } feedData.Items.Add(feedItem); } }
return feedData;
When the code gets to the return statement, it's not actually returning in the sense that a synchronous method returns. Remember that the method returned to the caller immediately after the "await" statement. It returned aTask<FeedData> to represent the eventual result of the method. Here, you finally get the result. The line return feedData;, gives the FeedData object that is the result of the method to the Task<FeedData> that is waiting for it.
The Task was awaited at this line in the GetFeedsAsync method.
C#
VB
this.Feeds.Add(await feed1);
When the Task gets the FeedData result that it's waiting for, the code execution proceeds and the FeedData is added to the FeedDataSource.Feeds collection.

Using the data in the app

To use the data in the app, you create an instance of the data source as a resource in App.xaml. You name the instance feedDataSource.
BR211380.wedge(en-us,WIN.10).gifTo add a resource to an app
  1. Double-click App.xaml in Solution Explorer. The file opens in the XAML editor.
  2. Add the resource declaration, <local:FeedDataSource x:Key="feedDataSource"/>, to the root ResourceDictionary, after the MergedDictionaries collection.
Here's the complete XAML for the Application.Resources section after you add the new resource.
XAML
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!--
Styles that define common aspects of the platform look and feel
Required by Visual Studio project and item templates -->
</ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Common/StandardStyles.xaml"/> <local:FeedDataSource x:Key="feedDataSource"/>
</ResourceDictionary>
</Application.Resources>
To retrieve the feeds, you add code to the OnLaunched method override in the App.xaml.cs/vb file. This method is executed each time a user launches the app.
Here, you add the async keyword to the method declaration because you use the await keyword inside the method. Because the app requires an active internet connection to download feeds, you use theNetworkInformation class to check for a connection. If the app is connected, you download the feeds; otherwise, you notify the user. You add code to get the app's instance of FeedDataSource and check to see if it already contains feeds. If it doesn't, you call the FeedDataSource.GetFeedsAsync method to retrieve the feeds.
BR211380.wedge(en-us,WIN.10).gifTo retrieve the feeds
  1. Double-click App.xaml.cs/vb in Solution Explorer. The file opens in the code editor.
  2. Add the async keyword to the OnLaunched method signature.
    C#
    VB
    protected async override void OnLaunched(LaunchActivatedEventArgs args)
  3. Add this code to the OnLaunched method, immediately after the instantiation of the new FramerootFrame = New Frame().
    C#
    VB
    // Add this code after "rootFrame = new Frame();"
    var connectionProfile = Windows.Networking.Connectivity.NetworkInformation.GetInternetConnectionProfile();
    if (connectionProfile != null) {
    if (feedDataSource != null)
    FeedDataSource feedDataSource = (FeedDataSource)App.Current.Resources["feedDataSource"]; {
    }
    if (feedDataSource.Feeds.Count == 0) { await feedDataSource.GetFeedsAsync(); }
    var messageDialog = new Windows.UI.Popups.MessageDialog("An internet connection is needed to download feeds. Please check your connection and restart the app.");
    } else { var result = messageDialog.ShowAsync(); }
Here's the full code for the OnLaunched method after you add the code.
C#
VB
protected async override void OnLaunched(LaunchActivatedEventArgs args)
{ Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active if (rootFrame == null) {
// Add this code after "rootFrame = new Frame();"
// Create a Frame to act as the navigation context and navigate to the first page rootFrame = new Frame();
FeedDataSource feedDataSource = (FeedDataSource)App.Current.Resources["feedDataSource"];
var connectionProfile = Windows.Networking.Connectivity.NetworkInformation.GetInternetConnectionProfile(); if (connectionProfile != null) { if (feedDataSource != null) {
var messageDialog = new Windows.UI.Popups.MessageDialog("An internet connection is needed to download feeds. Please check your connection and restart the app.");
if (feedDataSource.Feeds.Count == 0) { await feedDataSource.GetFeedsAsync(); } } } else { var result = messageDialog.ShowAsync();
Window.Current.Content = rootFrame;
} if (args.PreviousExecutionState == ApplicationExecutionState.Terminated) { //TODO: Load state from previously suspended application } // Place the frame in the current Window }
if (!rootFrame.Navigate(typeof(ItemsPage), args.Arguments))
if (rootFrame.Content == null) { // When the navigation stack isn't restored navigate to the first page, // configuring the new page by passing required information as a navigation // parameter {
throw new Exception("Failed to create initial page"); } } // Ensure the current window is active Window.Current.Activate();
}
You can build and run the app in debugging mode to make sure it builds and retrieves the feeds without error. If there are no errors, the app runs, but only shows a black screen. If there are errors, Visual Studio shows info about the error. To learn more about running apps in Visual Studio, see Running Windows Store apps from Visual Studio.
BR211380.wedge(en-us,WIN.10).gifTo run the app in debugging mode
  1. To run the app, do one of these:
    • Click Debug > Start debugging.
    • Press F5.
  2. To stop debugging:
    1. Press Alt+Tab to return to Visual Studio.
    2. In Visual Studio, do one of these.
      • Click Debug > Stop debugging.
      • Press Shift+F5.
Now you create the UI to show the data.

Adding pages and navigation

To show the Windows team blogs, you must add pages to the app and handle navigation between these pages. First, you want a page that lists all of the Windows team blogs. When a reader picks a blog from this page, you navigate to a new page and load the list of posts for that blog. You also add a detail page so a user can read individual blog posts without the list view taking up space.

Page templates

Fortunately, you don't have to create each page from a blank template. Visual Studio Express 2012 for Windows 8 ships with a collection of page templates that are useful for a variety of situations. Here are the available page templates.
PAGE TYPEDESCRIPTION
Group Detail PageDisplays details for a single group and previews for each item in the group.
Grouped Items PageDisplays grouped collections.
Item Detail PageDisplays one item in detail, and enables navigation to adjacent items.
Items PageDisplays a collection of items.
Split PageDisplays a list of items and details for the selected item.
Basic PageAn empty page that can adapt to different orientations and views, and has a title and back button.
Blank PageA blank page for a Windows Store app.
You use the Items Page template to show the list of Windows team blogs. You use the Split Page template to show the posts for each blog, and the text of the selected post. You use the Basic Page template for the detail page.
BR211380.wedge(en-us,WIN.10).gifTo add pages to the app
  1. Select Project > Add New Item. The Add New Item dialog opens.
    Here's the Add New Item dialog.
    Visual Studio Add New Item dialog.
  2. Under Visual C# or Visual Basic in the left pane, pick the Windows Store template type.
  3. In the center pane, select the type of page to add to your project. Select the Items Page template.
  4. Enter a name for the page. Enter "ItemsPage.xaml".
  5. Click Add.
    The first time you add a new page to the Blank App template (other than a Blank Page), Visual Studio shows a dialog with a message that you need to add files that are missing from your project. Click Yes to add these files. Files for several utility classes are added to your project in the Common folder.
    The XAML and code behind files for your page are added to the project.
  6. Click Build > Build solution to build the app. The new page will show an error in the designer until you build the helper classes it depends on.
  7. Repeat steps 1-5 to add a split page.
    • In step 3, select the Split Page template.
    • In step 4, name the page, "SplitPage.xaml".
  8. Repeat steps 1-5 to add a basic page.
    • In step 3, select the Basic Page template.
    • In step 4, name the page, "DetailPage.xaml".
When you add the page templates to your project and look at the XAML and code behind, it's apparent that these page templates do a lot of work for you. In fact, it's easy to get lost, so let's take a closer look at the page templates and see what's in them. All the XAML page templates for Windows Store apps have the same format.
The XAML for the page templates has 3 main sections:
ResourcesStyles and data templates for the page are defined in the Resources section. We talk more about this in the Creating a consistent look with styles section.
App ContentThe controls and content that make up the app UI are defined within the root layout panel.
Visual State ManagerAnimations and transitions that adapt the app to different layouts and orientations are defined in the VisualStateManager section. We talk more about this in the Adapting to different layoutssection.
The template pages you use are all derived from the LayoutAwarePage class and can do much more by default than the Blank Page that's used for the MainPage.xaml in a Blank app. LayoutAwarePage is an implementation of Pagethat enables important functionality for Windows Store app development:
  • The mapping of application view state to visual state lets the page adapt to different resolutions, orientations, and views.
  • GoBack and GoHome event handlers support basic navigation.
  • A default view model gives you a simple bindable data source.
  • SaveState and LoadState methods work with the SuspensionManager class to manage app session state.
The page templates also use styles and templates found in StandardStyles.xaml that apply the design guidelines for Windows Store apps. You'll use some of these styles as a starting point and modify copies of them to customize the look of the app.

Navigating between pages

The XAML UI framework provides a built-in navigation model that uses Frames and Pages and works much like the navigation in a web browser. The Frame control hosts Pages, and has a navigation history that you can use to go forward and back through pages you've visited. You can pass data between pages as you navigate.

Navigating to ItemsPage

In the Visual Studio project templates, a Frame named rootFrame is set as the content of the app window. ThisFrame hosts all the Pages in the app. Let's look at the relevant code in App.xaml.cs/vb.
C#
VB
protected async override void OnLaunched(LaunchActivatedEventArgs args)
{ Frame rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active if (rootFrame == null) {
// Create a Frame to act as the navigation context and navigate to the first page rootFrame = new Frame(); ...
// When the navigation stack isn't restored navigate to the first page,
// Place the frame in the current Window Window.Current.Content = rootFrame; } if (rootFrame.Content == null) {
throw new Exception("Failed to create initial page");
// configuring the new page by passing required information as a navigation // parameter if (!rootFrame.Navigate(typeof(MainPage), args.Arguments)) { } }
// Ensure the current window is active Window.Current.Activate();
}
This code gets an existing Frame if there is one; otherwise, it creates a new one and sets it as the window's content. It then navigates to MainPage. Because you want the first page in the app to be ItemsPage, you change the call to the Navigate method and pass in ItemsPage as the Page to navigate to.
BR211380.wedge(en-us,WIN.10).gifTo navigate to ItemsPage
  1. Double-click App.xaml.cs/vb in Solution Explorer. The file opens in the code editor.
  2. In the OnLaunched method, update the call to rootFrame.Navigate and pass ItemsPage as the first parameter as shown here.
    C#
    VB
    if (!rootFrame.Navigate(typeof(ItemsPage), args.Arguments))
    {
    }
    throw new Exception("Failed to create initial page");
  3. Press F5 to build and run the app. Now the ItemsPage is loaded instead of the default MainPage.
    Note  The default MainPage.xaml file is no longer needed in this project, and you can safely delete it.
In the items page, you don't see any content yet because you haven't connected any data to the UI. You do that now.

Loading ItemsPage

When ItemsPage is loaded, you need to get the app's instance of the data source and hook it up to the UI. For pages that are derived from LayoutAwarePage, you can hook up your data to the DefaultViewModel provided byLayoutAwarePage. You do this in the LoadState method override.
BR211380.wedge(en-us,WIN.10).gifTo load data in the items page
  1. Double-click ItemPage.xaml.cs/vb in Solution Explorer to open it.
  2. Add this code to the LoadState method.
    C#
    VB
    FeedDataSource feedDataSource = (FeedDataSource)App.Current.Resources["feedDataSource"];
    if (feedDataSource != null) {
    this.DefaultViewModel["Items"] = feedDataSource.Feeds;
    }
  3. Press F5 to build and run the app.
Now the ItemsPage is loaded and shows a grid of all the blogs. It looks something like this, but the items might be arranged differently depending on your screen resolution.
Items page

Navigating to SplitPage

When the user picks a blog from the collection, you navigate from the items page to the split page . To do this navigation, you want the GridView items to respond to a click like a button, instead of being selected. To make the GridView items clickable, you set the SelectionMode and IsItemClickEnabled properties as shown here. You then add a handler for GridView's ItemClick event.
BR211380.wedge(en-us,WIN.10).gifTo navigate to SplitPage
  1. Double-click ItemsPage.xaml in Solution Explorer to open it.
  2. Select the GridView control named itemGridView.
  3. In the Properties panel, expand the Common section, then click the down arrow at the bottom of the section to expand the advanced properties.
  4. Check the box for the IsItemClickEnabled property. This sets the property to true.
  5. Add a handler for the ItemClick event.
    1. In the Properties panel, click the Events button (Events button).
    2. Find the ItemClick event in the event list. In the text box for the event, type "ItemView_ItemClick" for the name of the method that handles the ItemClick event.
    3. Press Enter. The event handler method is created and opened in the code editor so you can add code that's executed when the event occurs.
    4. Add this code to the ItemView_ItemClick event handler in the code behind page.
      Here, you navigate to the split page and pass the title of the selected feed.
      C#
      VB
      // Navigate to the split page, configuring the new page
      // by passing the title of the clicked item as a navigation parameter
      if (e.ClickedItem != null) {
      this.Frame.Navigate(typeof(SplitPage), title);
      string title = ((FeedData)e.ClickedItem).Title; }
  6. In ItemsPage.xaml, select the ListView control named itemListView.
  7. In the Properties Window, click the Properties button (Events button).
  8. Repeat steps 4-5.3 for the itemListView control.
The itemListView list is shown in place of the grid when the app is Snapped. We talk more about this in the sectionAdapting to different layouts. For now, you just make the same changes to the ListView that you made to theGridView so they have the same behavior.
To navigate between pages, you use the Frame control's NavigateGoForward, and GoBack methods. To navigate back, the Visual Studio page templates include a Back button. The handler for the BackButton's Clickevent calls the Frame.GoBack method.
The Navigate(TypeName, Object) method lets you navigate and pass a data object to the new page. You use this method to pass data between your pages. The first parameter, typeof(SplitPage), is the Type of the page that you are navigating to. The second parameter is the data object that you pass to the page you're navigating to. In this case, you pass the title of the clicked item.
You could pass your custom data objects as navigation parameters, but they won't be persisted and will even cause an exception when you save the app's session state using the SuspensionManager class. In order to save the navigation state of the app using SuspensionManager, you must pass only basic, serializable types as the navigation parameter. That's why you pass the title of the item, and have a method in the FeedDataSource class to get the item from the title.
Before you move on to the split page, you need to make one more change to the items page. The default page title is "My Application". You change this to "Windows Team Blogs".
BR211380.wedge(en-us,WIN.10).gifTo change the page title
  1. Double-click ItemsPage.xaml in Solution Explorer to open it.
  2. Select the TextBlock named pageTitle.
  3. In the Properties Window, click the Properties button (Events button).
  4. Under Common in the Properties panel, click the property marker for the Text property. The property menu opens.
    Note  The property marker is the small box symbol to the right of each property value. The Text property marker is green to indicate that it's set to a resource.
  5. In the property menu, select Edit Resource.... The Edit Resource dialog opens.
  6. In the Edit Resource dialog, change the value from "My Application" to "Windows Team Blogs".
  7. Click OK.
In ItemsPage.xaml, the page title is bound to a static resource with the key AppName. The text in this resource is updated to "Windows Team Blogs", and the XAML now looks like this.
XAML
<x:String x:Key="AppName">Windows Team Blogs</x:String>
Press F5 to build and run the app. Now when you click an item the split page is loaded. But the split page is still blank because you haven't connected it to the data yet.

Loading SplitPage

In the SplitPage.xaml.cs/vb code behind page, you need to do something with the object that was just passed from the items page. For this, you again override the LoadState method. This method is already added in the page template code, so you just need to modify it to hook up your data. The navigationParameter has the data object that was passed from the items page. You cast this back to a string, and then pass it as the parameter to theFeedDataSource.GetFeed method. You add the returned feed data to DefaultViewModel with the key Feed, and add theFeedData.Items property to DefaultViewModel with the key Items.
BR211380.wedge(en-us,WIN.10).gifTo load data in the split page
  1. Double-click SplitPage.xaml.cs/vb in Solution Explorer to open it in the code editor.
  2. Add this code to the top of the LoadState method, after the "TODO" comments.
    Tip  Expand the "Page state management" region to see the LoadState method.
    C#
    VB
    // TODO: Assign a bindable group to this.DefaultViewModel["Group"]
    // TODO: Assign a collection of bindable items to this.DefaultViewModel["Items"]
    string feedTitle = (string)navigationParameter;
    if (feedData != null)
    FeedData feedData = FeedDataSource.GetFeed(feedTitle); {
    }
    this.DefaultViewModel["Feed"] = feedData; this.DefaultViewModel["Items"] = feedData.Items;
Here's the updated LoadState method.
C#
VB
protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{ // TODO: Assign a bindable group to this.DefaultViewModel["Group"]
string feedTitle = (string)navigationParameter;
// TODO: Assign a collection of bindable items to this.DefaultViewModel["Items"] FeedData feedData = FeedDataSource.GetFeed(feedTitle);
}
if (feedData != null) { this.DefaultViewModel["Feed"] = feedData; this.DefaultViewModel["Items"] = feedData.Items;
// navigation is being used (see the logical page navigation #region below.)
if (pageState == null) { // When this is a new page, select the first item automatically unless logical page
}
if (!this.UsingLogicalPageNavigation() && this.itemsViewSource.View != null) { this.itemsViewSource.View.MoveCurrentToFirst(); } else {
// TODO: Invoke this.itemsViewSource.View.MoveCurrentTo() with the selected
// Restore the previously saved state associated with this page if (pageState.ContainsKey("SelectedItem") && this.itemsViewSource.View != null) { // item as specified by the value of pageState["SelectedItem"] }
}
}
Press F5 to build and run the app. Now when you navigate to the split page, the data is displayed and you can select from the list of blog posts. But the page title is still blank. You'll fix that now.
In the Visual Studio page template, the "TODO" comments indicate where you add your data object toDefaultViewModel with the key Group.
C#
VB
// TODO: Assign a bindable group to this.DefaultViewModel["Group"]
... this.DefaultViewModel["Feed"] = feedData;
You can think of a blog feed as a group of blog posts, but it makes the code easier to read if you use the key Feedin place of Group. Because you used the key Feed instead, you need to change the binding in the page title to bind to the Feed property instead of Group. You also make the title span 2 columns so it's not cut off.
BR211380.wedge(en-us,WIN.10).gifTo update the page title
  1. Double-click SplitPage.xaml in Solution Explorer to open it.
  2. Select the Grid named titlePanel.
  3. Under Layout in the Properties panel, set the ColumnSpan property to "2" and press Enter.
    Note  At the default width of the Properties panel, the ColumnSpan property is shown as Colum....
    The XAML is updated as shown here.
    XAML
    <!-- Back button and page title -->
    <Grid x:Name="titlePanel" Grid.ColumnSpan="2">
  4. Select the TextBlock named pageTitle.
  5. Under Common in the Properties panel, click the property marker for the Text property. The property menu opens.
    Note  The Text property marker is orange to indicate that it's set to a binding.
  6. In the property menu, select Create Data Binding.... The Create Data Binding dialog opens.
  7. In the Create Data Binding dialog, change the value in the Path text box to "Feed.Title" and click OK.
    The XAML for the TextBlock is updated like this.
    XAML
    <TextBlock x:Name="pageTitle" Grid.Column="1" Text="{Binding Feed.Title}"
    Style="{StaticResource PageHeaderTextStyle}"/>
  8. Press F5 to build and run the app. Now when you navigate to the split page, the page title is shown.
Split page with default styles

Add the WebView

By default, the split page template shows the details for the selected item in a TextBlock. However, the string that contains the post content is not plain text, but a string of HTML. When you show the string in a TextBlock, you see a bunch of HTML tags, which is not what you want. Instead, you use a WebView control to display the HTML. You also change the layout used to show the title and content of the selected blog post.
BR211380.wedge(en-us,WIN.10).gifTo add the web view
  1. In SplitPage.xaml, delete the ScrollViewer named itemDetail and all of its contents.
  2. In the XAML editor, add this XAML in place of the itemDetail ScrollViewer you deleted.
    XAML
    <!-- Details for selected item -->
    <ScrollViewer
    AutomationProperties.AutomationId="ItemDetailScrollViewer"
    x:Name="itemDetail"
    Padding="70,0,120,0"
    Grid.Column="1" Grid.Row="1"
    DataContext="{Binding SelectedItem, ElementName=itemListView}"
    Style="{StaticResource VerticalScrollViewerStyle}"> <Grid x:Name="itemDetailGrid">
    <RowDefinition Height="*"/>
    <Grid.RowDefinitions> <RowDefinition Height="Auto"/> </Grid.RowDefinitions>
    <Border x:Name="contentViewBorder" BorderBrush="Gray" BorderThickness="2"
    <TextBlock x:Name="itemTitle" Text="{Binding Title}" Style="{StaticResource SubheaderTextStyle}"/> Grid.Row="1" Margin="0,15,0,20">
    </Grid>
    <Grid> <WebView x:Name="contentView" /> <Rectangle x:Name="contentViewRect" /> </Grid> </Border>
    </ScrollViewer>
The WebView control gives you a way to host HTML data within your app. But if you look at its Source property, you see that it takes the Uri of the web page to display. Your HTML data is just a string of HTML. It doesn't have aUri that you can bind to the Source property. Luckily, there is a NavigateToString method that you can pass your string of HTML to.
Whenever you use a WebView control to view content that might not be available, handle any failures that occur.
Here, you handle the NavigationFailed event to show the error message in the WebView control if the navigation fails.
BR211380.wedge(en-us,WIN.10).gifTo handle navigation errors
  1. Select the WebView named contentView that you added in the previous step.
  2. In the Properties Window, click the Events button (Events button).
  3. Find the NavigationFailed event in the event list. In the text box for the event, type "ContentView_NavigationFailed" for the name of the method that handles the NavigationFailed event.
  4. Press Enter. The event handler method is created and opened in the code editor so you can add code that's executed when the event occurs.
  5. Add this code to the ContentView_NavigationFailed event handler in the code behind page.
    C#
    VB
    string errorString = "<p>Page could not be loaded.</p><p>Error is: " + e.WebErrorStatus.ToString() + "</p>";
    this.contentView.NavigateToString(errorString);
To populate the WebView, you add your code to the ItemListView_SelectionChanged event handler. In the event handler, you cast the selected item to a FeedItem and get the string of HTML from the Content property. You then pass the string to the NavigateToString method. If no item is selected, you clear the WebView by passing an empty string.
BR211380.wedge(en-us,WIN.10).gifTo populate the web view
  1. Double-click SplitPage.xaml.cs/vb in Solution Explorer. The file opens in the code editor.
  2. Add this code to the end of the ItemListView_SelectionChanged method to populate the WebView with the content of the selected blog post.
    Note  Expand the "Logical page navigation" region to see the ItemListView_SelectionChanged method.
    C#
    VB
    // Add this code to populate the web view
    // with the content of the selected blog post.
    Selector list = sender as Selector;
    FeedItem selectedItem = list.SelectedItem as FeedItem;
    if (selectedItem != null) {
    {
    this.contentView.NavigateToString(selectedItem.Content); } else
    this.contentView.NavigateToString(""); }
  3. Press F5 to build and run the app.
The split page is looking better now, and shows the selected blog post in a more readable format.
Split page with default styles

Load DetailPage

Now you add content to the detail page. In DetailPage.xaml, you need to bind the title TextBlock to the blog post title and add a WebView control to show the blog page.
BR211380.wedge(en-us,WIN.10).gifTo update the detail page
  1. Double-click DetailPage.xaml in Solution Explorer to open it.
  2. Bind the page title TextBlock to the Title property of the selected blog post.
    1. Select the TextBlock named pageTitle.
    2. In the Properties Window, click the Properties button (Events button).
    3. Under Common in the Properties panel, click the property marker for the Text property. The property menu opens.
    4. In the property menu, select Create Data Binding.... The Create Data Binding dialog opens.
    5. In the Create Data Binding dialog, select Data context in the Binding type drop-down list.
    6. Enter "Title" in the Path text box then click OK.
      Note  The message in the Create Data Binding dialog says the data context is not set. That's okay because you set the data context in code when the you run the app.
  3. In the XAML editor, add this XAML after the Grid that has the page title, and before theVisualStateManager.VisualStateGroups section.
    XAML
    <Border x:Name="contentViewBorder" BorderBrush="Gray" BorderThickness="2"
    Grid.Row="1" Margin="120,15,20,20">
    NavigationFailed="ContentView_NavigationFailed"/>
    <WebView x:Name="contentView" </Border>
  4. Double-click DetailPage.xaml.cs/vb in Solution Explorer to open it.
  5. Add this code to the LoadState method override.
    This code navigates the WebView to the Uniform Resource Identifier (URI) of the blog post and sets theDataContext of the page.
    C#
    VB
    // Add this code to navigate the web view to the selected blog post.
    string itemTitle = (string)navigationParameter;
    if (feedItem != null)
    FeedItem feedItem = FeedDataSource.GetItem(itemTitle); {
    this.contentView.Navigate(feedItem.Link); this.DataContext = feedItem; }
  6. Add this code to the DetailPage class to handle the WebView.NavigationFailed event.
    C#
    VB
    private void ContentView_NavigationFailed(object sender, WebViewNavigationFailedEventArgs e)
    {
    string errorString = "<p>Page could not be loaded.</p><p>Error is: " + e.WebErrorStatus.ToString() + "</p>";
    this.contentView.NavigateToString(errorString); }
  7. Press F5 to build and run the app.
    All the data is hooked up now, but there's no way to navigate to the details page you created. You add navigation to the detail page next.

Adding an app bar

Most of the navigation in the blog reader app happens when the user picks an item in the UI. But on the split page, you must provide a way for the user to go to the detail view of the blog post. You could put a button somewhere on the page, but that would distract from the core app experience, which is reading. Instead, you put the button in an app bar that's hidden until the user needs it.
An app bar is a piece of UI that is hidden by default, and is shown or dismissed when the user swipes from the edge of the screen or interacts with the app. It presents navigation, commands, and tools to the user. An app bar can appear at the top of the page, at the bottom of the page, or both. We recommend that you put navigation in the top app bar, and tools and commands in the bottom app bar. You can control how and when the app bar is shown and dismissed by setting the IsSticky and IsOpen properties. You can also respond to the app bar being opened or dismissed by handling the Opened and Closed events.
To add an app bar in XAML, you assign an AppBar control to a Page's TopAppBar or BottomAppBar property. You'll add a top app bar with a button to navigate to the detail page. The StandardStyles.xaml file contains a variety of app bar button styles for common scenarios. You use these styles as a guide to create a style for your button. You put your style in the Page.Resources section of SplitPage.xaml, and add the Page.TopAppBar XAML just after the resources section.
BR211380.wedge(en-us,WIN.10).gifTo add an app bar
  1. Double-click SplitPage.xaml in Solution Explorer to open it.
  2. In the XAML editor, add this XAML in the Page.Resources section near the top of the page.
    This adds the Style resource for the app bar button. We talk more about styles later in the section Creating a consistent look with styles.
    XAML
    <Style x:Key="WebViewAppBarButtonStyle" TargetType="Button"
    BasedOn="{StaticResource AppBarButtonStyle}">
    <Setter Property="AutomationProperties.AutomationId" Value="WebViewAppBarButton"/>
    <Setter Property="AutomationProperties.Name" Value="View Web Page"/> <Setter Property="Content" Value="&#xE12B;"/> </Style>
  3. Add this XAML after the Page.Resources section of the page.
    This adds an AppBar control to the TopAppBar property of the page.
    XAML
    <Page.TopAppBar>
    <AppBar Padding="10,0,10,0">
    <Grid>
    <Button HorizontalAlignment="Right"
    Style="{StaticResource WebViewAppBarButtonStyle}"/>
    </Grid> </AppBar> </Page.TopAppBar>
  4. Select the Button in the app bar you just added.
  5. In the Properties Window, click the Events button (Events button).
  6. Find the Click event at the top of the event list. In the text box for the event, enter "ViewDetail_Click" for the name of the method that handles the Click event.
  7. Press Enter. The event handler method is created and opened in the code editor so you can add code that's executed when the event occurs.
  8. Add this code to the event handler method to handle navigation to the detail page.
    C#
    VB
    FeedItem selectedItem = this.itemListView.SelectedItem as FeedItem;
    if (selectedItem != null && this.Frame != null) {
    this.Frame.Navigate(typeof(DetailPage), itemTitle);
    string itemTitle = selectedItem.Title; }
  9. Press F5 to build and run the app. Click a blog to navigate to the split page, and select a blog post to read. Right-click the page header to show the app bar, and click the Show Web View button to navigate to the detail page.
In Next blog we will add animations

No comments:

Post a Comment

Android Studio Project Structure

Android Project Structure In this blog i have explained Android project structure and file organization in detail, by creating a new An...