xaml语言建立首个win8 Metro应用,rss阅读器
本实例是来源msdn的Metro开发文档,按着解说一步步来理解的,修改了一点点,拿了博客园本人的博客作为RSS阅读,本实例用来学习还是可以的
参考文档http://msdn.microsoft.com/zh-cn/library/windows/apps/br211380.aspx#Y909
先看允许结果
本例子主要有2个类文件和2个xaml文件
第一个类文件FeedData.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Windows.Web.Syndication;
using Windows.Globalization.DateTimeFormatting;
namespace sl
{
// FeedData
// Holds info for a single blog feed, including a list of blog posts (FeedItem)
public class FeedData
{
public string Title { get; set; }
public string Description { get; set; }
public DateTime PubDate { get; set; }
private List<FeedItem> _Items = new List<FeedItem>();
public List<FeedItem> Items
{
get
{
return this._Items;
}
}
}
// FeedItem
// Holds info for a single blog post
public class FeedItem
{
public string Title { get; set; }
public string Author { get; set; }
public string Content { get; set; }
public DateTime PubDate { get; set; }
public Uri Link { get; set; }
}
// FeedDataSource
// Holds a collection of blog feeds (FeedData), and contains methods needed to
// retreive the feeds.
public class FeedDataSource
{
private ObservableCollection<FeedData> _Feeds = new ObservableCollection<FeedData>();
public ObservableCollection<FeedData> Feeds
{
get
{
return this._Feeds;
}
}
public async Task GetFeedsAsync()
{
Task<FeedData> feed1 =
GetFeedAsync(" http://feed.cnblogs.com/blog/u/109818/rss");
this.Feeds.Add(await feed1);
}
private async Task<FeedData> GetFeedAsync(string feedUriString)
{
// using Windows.Web.Syndication;
SyndicationClient client = new SyndicationClient();
Uri feedUri = new Uri(feedUriString);
try
{
SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri);
// This code is executed after RetrieveFeedAsync returns the SyndicationFeed.
// Process it and copy the data we want into our FeedData and FeedItem classes.
FeedData feedData = new FeedData();
feedData.Title = feed.Title.Text;
if (feed.Subtitle.Text != null)
{
feedData.Description = feed.Subtitle.Text;
}
// 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;
feedItem.PubDate = item.PublishedDate.DateTime;
feedItem.Author = item.Authors[0].Name.ToString();
// Handle the differences between RSS and Atom feeds.
if (feed.SourceFormat == SyndicationFormat.Atom10)
{
feedItem.Content = item.Content.Text;
feedItem.Link = new Uri("http://www.cnblogs.com" + item.Id);
}
else if (feed.SourceFormat == SyndicationFormat.Rss20)
{
feedItem.Content = item.Summary.Text;
feedItem.Link = item.Links[0].Uri;
}
feedData.Items.Add(feedItem);
}
return feedData;
}
catch (Exception)
{
return null;
}
}
}
}
第2个类文件DateConverter.cs
主要负责数据的转换
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Windows.Web.Syndication;
using Windows.Globalization.DateTimeFormatting;
namespace sl
{
public class DateConverter : Windows.UI.Xaml.Data.IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string culture)
{
if (value == null)
throw new ArgumentNullException("value", "Value cannot be null.");
if (!typeof(DateTime).Equals(value.GetType()))
throw new ArgumentException("Value must be of type DateTime.", "value");
DateTime dt = (DateTime)value;
if (parameter == null)
{
// Date "7/27/2011 9:30:59 AM" returns "7/27/2011"
return DateTimeFormatter.ShortDate.Format(dt);
}
else if ((string)parameter == "day")
{
// Date "7/27/2011 9:30:59 AM" returns "27"
DateTimeFormatter dateFormatter = new DateTimeFormatter("{day.integer(2)}");
return dateFormatter.Format(dt);
}
else if ((string)parameter == "month")
{
// Date "7/27/2011 9:30:59 AM" returns "JUL"
DateTimeFormatter dateFormatter = new DateTimeFormatter("{month.abbreviated(3)}");
return dateFormatter.Format(dt).ToUpper();
}
else if ((string)parameter == "year")
{
// Date "7/27/2011 9:30:59 AM" returns "2011"
DateTimeFormatter dateFormatter = new DateTimeFormatter("{year.full}");
return dateFormatter.Format(dt);
}
else
{
// Requested format is unknown. Return in the original format.
return dt.ToString();
}
}
public object ConvertBack(object value, Type targetType, object parameter, string culture)
{
string strValue = value as string;
DateTime resultDateTime;
if (DateTime.TryParse(strValue, out resultDateTime))
{
return resultDateTime;
}
return Windows.UI.Xaml.DependencyProperty.UnsetValue;
}
}
}
第一个界面文件BlankPage.xaml文件(包括两段代码)
xaml代码
<Page
x:Class="sl.BlankPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:sl"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{StaticResource ApplicationPageBackgroundBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="140" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Title -->
<TextBlock x:Name="TitleText" Text="{Binding Title}"
VerticalAlignment="Center" FontSize="48" Margin="56,0,0,0"/>
<!-- Content -->
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" MinWidth="320" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<!-- Left column -->
<!-- The default value of Grid.Column is 0, so we do not need to set it
to make the ListView show up in the first column. -->
<ListView x:Name="ItemListView"
ItemsSource="{Binding Items}"
Margin="60,0,0,10"
SelectionChanged="ItemListView_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Title}"
FontSize="24" Margin="5,0,0,0" TextWrapping="Wrap" />
<TextBlock Text="{Binding Author}"
FontSize="16" Margin="15,0,0,0"/>
<TextBlock Text="{Binding Path=PubDate, Converter={StaticResource dateConverter}}"
FontSize="16" Margin="15,0,0,0"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!-- Right column -->
<!-- We use a Grid here instead of a StackPanel so that the WebView sizes correctly. -->
<Grid DataContext="{Binding ElementName=ItemListView, Path=SelectedItem}"
Grid.Column="1" Margin="25,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock x:Name="PostTitleText" Text="{Binding Title}" FontSize="24"/>
<WebView x:Name="ContentView" Grid.Row="1" Margin="0,5,20,20"/>
</Grid>
</Grid>
</Grid>
</Page>
C#代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Windows.Web.Syndication;
using Windows.Globalization.DateTimeFormatting;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace sl
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class BlankPage : Page
{
public BlankPage()
{
this.InitializeComponent();
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property is typically used to configure the page.</param>
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
FeedDataSource _feedDataSource = App.DataSource;
if (_feedDataSource.Feeds.Count == 0)
{
await _feedDataSource.GetFeedsAsync();
}
this.DataContext = (_feedDataSource.Feeds).First();
}
private void ItemListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
FeedItem feedItem = e.AddedItems[0] as FeedItem;
if (feedItem != null)
{
// Navigate the WebView to the blog post content HTML string.
ContentView.NavigateToString(feedItem.Content);
}
}
}
}
第4个文件是App.xaml(包括2段代码)
xaml代码
<Application
x:Class="sl.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:sl">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<local:FeedDataSource x:Key="feedDataSource"/>
<!-- Add the DateConverter here. -->
<local:DateConverter x:Key="dateConverter" />
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
C#代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using Windows.Web.Syndication;
using Windows.Globalization.DateTimeFormatting;
// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227
namespace sl
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
sealed partial class App : Application
{
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public static FeedDataSource DataSource;
public App()
{
this.InitializeComponent();
DataSource = new FeedDataSource();
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used when the application is launched to open a specific file, to display
/// search results, and so forth.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
// Create a Frame to act navigation context and navigate to the first page
var rootFrame = new Frame();
rootFrame.Navigate(typeof(BlankPage));
// Place the frame in the current Window and ensure that it is active
Window.Current.Content = rootFrame;
Window.Current.Activate();
}
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
void OnSuspending(object sender, SuspendingEventArgs e)
{
//TODO: Save application state and stop any background activity
}
}
}
源于参考文档http://msdn.microsoft.com/zh-cn/library/windows/apps/br211380.aspx#Y909
本是菜鸟,偶做老鸟,略读半卷书,坐井说天阔。大志无所为,海斗量得失,年到老时方恨晚,怒指生不逢时。