We deal with the development of Windows 8 applications on XAML / C #, implementing a simple RSS Reader. Part 2

  • Tutorial

We continue to develop a simple RSS reader. The beginning was made in the article Understanding the Development of Windows 8 Applications on XAML / C #, Implementing a Simple RSS Reader. Part 1 , where we created the project, received the RSS data and started doing it beautifully. In this part, we will add beauty and functionality to our reader.

Continue to do beautifully


Now we have beautiful tiles of different sizes, and, if desired, we can tile in different groups. Let's do it. We’ll make Stas Pavlov’s blog with tiles of different sizes, and for Sergey Pugachev’s Blog, we won’t spoil the user with such a variety.

How to do it? Everything is very simple. The logic that determines the size of the tiles is all implemented in the PrepareContainerForItemOverride function of the VariableSizeGridView class, so you can add the corresponding logic there.

To distinguish between groups, we will use UniqueID, for a group it corresponds to the URL on RSS. Add the following code to the PrepareContainerForItemOverride function:
int group = -1;
if (dataItem.Group.UniqueId.Contains("stas"))
{
    group = 1;
}


And now we will change the behavior of the function, depending on which group it works for. adding a condition.
if (group > 0)
{ 
    if (index == 2)
    {
        colVal = 2;
        rowVal = 4;
    }
    if (index == 5)
    {
        colVal = 4;
        rowVal = 4;
    }
}


Run the program to check how it works now.


We set ourselves an even more difficult task. But what if we need to use different display templates for display? This is also a solvable task. We will again have to implement our own class, which will contain logic, but now it will already inherit from DataTemplateSelector.

So, add a new class to the solution called MyDataTemplateSelector, indicate that it inherits from DataTemplateSelector. Add directives to using:
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

And redefine the SelectTemplateCore function. The result should be the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace MyReader
{
    class MyDataTemplateSelector : DataTemplateSelector
    {
        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            return base.SelectTemplateCore(item, container);
        }
    }
}

Now we need to define in the XAML file those templates from which we will choose. To do this, open GroupedItemsPage.xaml and go to the resources of the page where we have defined the CustomItemTemplate template:

Define another template with minimal changes - change the alignment:


Let's go back to our MyDataTemplateSelector class and add code that determines which template to use, depending on which element of which group is displayed:
using MyReader.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace MyReader
{
    class MyDataTemplateSelector : DataTemplateSelector
    {
        public DataTemplate Template1 { get; set; }
        public DataTemplate Template2 { get; set; }
        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            RSSDataItem dataItem = item as RSSDataItem;
            if (dataItem.Group.UniqueId.Contains("stas"))
            {
                return Template1;
            }
            else
                return Template2;
        }
    }
}


Go back to GroupedItemsPage.xaml and go to the resources of the page where we have defined the templates and initialize our selector:
And specify the selector in instead of specifying the template for Item for local: VariableSizeGridView:


We launch the application to make sure that everything works as planned.


Great, everything works as planned, you can go to work with live tiles.

But, before moving on to live tiles, let's change the style of the caption text on the tiles in the group.

Let's create the styles we need based on the BasicTextStyle style and place them in the resources of the GroupedItemsPage.xaml page:


And apply this style to the text in our templates:


Launch the application and see how the labels on the grouped elements now look.


Everything looks much better. If you want, you can play around with styles to achieve the desired effect.

Add live tiles


It's time to add live tiles. Since so far I have no service that monitors updates, our tiles will be updated when RSS is received, to please the user until the next launch of the application.

Let's go to the RSSDataSource.cs file and add the UpdateTile method to the RSSDataSource class:
public static void UpdateTile()
{
    var news = RSSDataSource.AllGroups[0].Items.ToList();            
    var xml = new XmlDocument();
    xml.LoadXml(
        string.Format(
            @"
    {0}{1}{2}{3}{0}{1}{2}{3}",
            news.Count > 0 ? System.Net.WebUtility.HtmlEncode(news[0].Title) : "",
            news.Count > 1 ? System.Net.WebUtility.HtmlEncode(news[1].Title) : "",
            news.Count > 2 ? System.Net.WebUtility.HtmlEncode(news[2].Title) : "",
            news.Count > 3 ? System.Net.WebUtility.HtmlEncode(news[3].Title) : ""));
    TileUpdateManager.CreateTileUpdaterForApplication().Update(new TileNotification(xml));
}

Remember to add the following directives to the using block:
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;

Here we create XML for updating tiles using templates, and actually updating the tiles themselves. The code is completely transparent. Since this is an example, I always take just the first RSS feed.

For this to work, you must add a call to this method to any place where RSS is already available. Let's add await to the AddGroupForFeedAsync called RSS feed methods and then we can safely call our function after adding the first feed.

We pass to the LoadState method in the GroupedItemsPage.xaml.cs file, add async to it, to the AddGroupForFeedAsync methods and add the call to UpdateTile ::
protected async override void LoadState(Object navigationParameter, Dictionary pageState)
{
   this.DefaultViewModel["Groups"] = RSSDataSource.AllGroups;
   await RSSDataSource.AddGroupForFeedAsync("http://blogs.msdn.com/b/stasus/rss.aspx");
   RSSDataSource.UpdateTile();
   RSSDataSource.AddGroupForFeedAsync("http://www.spugachev.com/feed");
}

I deliberately set aside one call without await - later - pay attention to how it looks when you start the application.

Now it remains to add WideLogo support to the application. To do this, create the Habr_WideLogo.scale-100.png file with a size of 310 by 150, add it to the Asset folder of the project. Next, double-click on the Package.appxmanifest file, open its visual editor and add WideLogo to the application:


Now we are fully ready to launch the application. Run it, then close it. Go to the start screen and make sure that live tiles work, both square and rectangular!

It's time to add contracts. Let's start with the Share contract. We implement a data source. We will fumble data on the RSS post page, providing the system with the maximum possible amount of data.

Let's move on to the code for the ItemDetailPage.xaml.cs page. In order to provide data to the system, it is necessary to handle the DataRequested event for the DataTransferManager. So, let's begin.

Add Share Contract


We register the DataRequested event handler in the NavigateTo page (and unsubscribe from the event in NavigateFrom), and implement the handler in which we will provide the system with the post name and text:
protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            DataTransferManager.GetForCurrentView().DataRequested += Share_DataRequested;
        }
        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            base.OnNavigatedFrom(e);
            DataTransferManager.GetForCurrentView().DataRequested -= Share_DataRequested;
        }
        private void Share_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
        {
            var selectedItem = (RSSDataItem)this.flipView.SelectedItem;
            args.Request.Data.Properties.Title = selectedItem.Title;
            args.Request.Data.Properties.Description = selectedItem.Content;
            args.Request.Data.SetText(selectedItem.Content);            
        }

Launch the application, go to the post page and verify that the application can now transfer data to other applications.


In fact, we get much more data for sharing in the RSS feed. This is a picture of a post, post URI, etc. I suggest that you independently modify the code of the method of adding a feed, as well as the associated classes, so that there is more data. More data - with a lot of applications you can share!

A sudden desire to talk about DataTemplateSelector made the article already large enough. Therefore, you have to do the third part. We will transfer the search and configuration contract to it, if possible - the background parallax and other useful things, and if it does not fit - I will do a few more parts.

The current application code can be downloaded from SkyDrive via a short link:aka.ms/w8RSSp2

UPD:
Part 1 of the cycle
Part 3 of the cycle

Also popular now: