本篇文章將撰寫一個應用程式,抓取【微軟最有價值專家 Microsoft MVP 台灣粉絲團】RSS 中的資料 Title、Links、PublishDate,經過資料整理與分析後顯示於 Windows Phone App 中。
本文刊載於
http://www.dotblogs.com.tw/chou/archive/2013/09/11/118178.aspx
在這篇文章您可以學到:
取得【微軟最有價值專家 Microsoft MVP 台灣粉絲團】RSS 網址
連結至粉絲團網址 https://www.facebook.com/twmvp,隨意點選任意照片,取得 ID 為 215783948459346
RSS 網址為 https://www.facebook.com/feeds/page.php?format=atom10&id=上述步驟取得的 ID
組合後的網址 https://www.facebook.com/feeds/page.php?format=atom10&id=215783948459346
程式開發
新增專案,在此我使用樞紐分析應用程式,名稱為 MvpRssPhoneApp。
先開啟 ItemViewModel.cs
修改 ItemViewModel 屬性為 Title、Links、PublishDate
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace MvpRssPhoneApp.ViewModels
{
public class ItemViewModel : INotifyPropertyChanged
{
private string _Title;
/// <summary>
/// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
/// </summary>
/// <returns></returns>
public string Title
{
get
{
return _Title;
}
set
{
if (value != _Title)
{
_Title = value;
NotifyPropertyChanged("Title");
}
}
}
private string _Links;
/// <summary>
/// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
/// </summary>
/// <returns></returns>
public string Links
{
get
{
return _Links;
}
set
{
if (value != _Links)
{
_Links = value;
NotifyPropertyChanged("Links");
}
}
}
private string _PublishDate;
/// <summary>
/// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
/// </summary>
/// <returns></returns>
public string PublishDate
{
get
{
return _PublishDate;
}
set
{
if (value != _PublishDate)
{
_PublishDate = value;
NotifyPropertyChanged("PublishDate");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
開啟 MainPage.xaml 設計畫面
在 StackPanel 內的顯示內容有兩個 TextBlock。
<StackPanel Margin="0,0,0,17">
<TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
我們多加一個 TextBlock,分別 Binding 屬性 Title、Links、PublishDate
<StackPanel Margin="0,0,0,17">
<TextBlock Text="{Binding Title}" TextWrapping="Wrap" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="{Binding Links}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
<TextBlock Text="{Binding PublishDate}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextAccentStyle}"/>
</StackPanel>
我們要做的事情是下載 RSS 資料,分析與加入資料,開啟 MainViewModel.cs
在 LoadData() 的部分,我們先修改成
/// <summary>
/// 建立並加入一些 ItemViewModel 物件到 Items 集合。
/// </summary>
public void LoadData()
{
// 範例資料; 以真實資料取代
this.Items.Add(new ItemViewModel() { Title = "測試標題" , Links = "http://www.dotblogs.com.tw/chou", PublishDate = DateTime.Now.ToString() });
this.IsDataLoaded = true;
}
執行看看,有資料了
接著,我們替換真實資料,修改 Load(),透過 WebClient 類別下載 RSS 資料。
/// <summary>
/// 建立並加入一些 ItemViewModel 物件到 Items 集合。
/// </summary>
public void LoadData()
{
WebClient webClient = new WebClient();
webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
webClient.DownloadStringAsync(new System.Uri("https://www.facebook.com/feeds/page.php?format=atom10&id=215783948459346"));
this.IsDataLoaded = true;
}
當非同步資源下載完成時,觸發 webClient_DownloadStringCompleted 事件,在事件中,如果下載 RSS 資料完成,則做進一步處理 (叫用 ProcessRssData 傳入下載 RSS 資料),沒有下載完成則報錯。
private void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error != null)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show(e.Error.Message);
});
}
else
{
ProcessRssData(e.Result);
}
}
在 ProcessRssData 中,將下載後的 RSS 資料,處理後加入 Items 中。
在 .NET framework 想要處理 Atom 1.0 和 RSS 2.0 可以透過 SyndicationFeed 類別
SyndicationFeed 類別 : 代表最上層的摘要的物件,<feed> 在 Atom 1.0 和 <rss> 以 RSS 2.0。
想要使用該類別,必須先加入參考,位置在
c:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\System.ServiceModel.Syndication.dll
加入時可能有警告視窗,請按是
加入完成
撰寫 PrcoessRssData,將下載後的 RSS 資料,透過 SyndicationFeed 類別解析後,將 Tilte、Links、PublishDate 屬性的資料,加入 Items 中。
private void ProcessRssData(string RssData)
{
StringReader stringReader = new StringReader(RssData);
XmlReader xmlReader = XmlReader.Create(stringReader);
SyndicationFeed feed = SyndicationFeed.Load(xmlReader);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
foreach (var item in feed.Items)
{
this.Items.Add(new ItemViewModel()
{
Title = HttpUtility.HtmlDecode(item.Title.Text),
Links = item.Links.Count > 0 ? item.Links[0].Uri.ToString() : string.Empty,
PublishDate = item.PublishDate.DateTime.ToString()
}
);
}
});
}
什麼時候會去呼叫 Model,開啟 MainPage.xaml.cs 程式碼,在 OnNavigatedTo 時,呼叫 Model 的 LoadData() 載入資料。
執行結果,Tilte 的資料看起來像是亂碼。
我們透過 HttpUtility.HtmlDecode 方法將已經為 HTTP 傳輸而進行 HTML 編碼的字串轉換為解碼的字串。
private void ProcessRssData(string RssData)
{
StringReader stringReader = new StringReader(RssData);
XmlReader xmlReader = XmlReader.Create(stringReader);
SyndicationFeed feed = SyndicationFeed.Load(xmlReader);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
foreach (var item in feed.Items)
{
this.Items.Add(new ItemViewModel()
{
Title = HttpUtility.HtmlDecode(item.Title.Text),
Links = item.Links.Count > 0 ? item.Links[0].Uri.ToString() : string.Empty,
PublishDate = item.PublishDate.DateTime.ToString()
}
);
}
});
}
重新執行,可顯示粉絲團上的資料。
其他相關資訊
<How to create a basic RSS reader for Windows Phone>
範例下載
http://www.dotblogs.com.tw/chou/archive/2013/09/11/118178.aspx
在這裡貼文
被 dotblogs 擋外連圖片就算了
沒想到看原文
http://www.dotblogs.com.tw/chou/archive/2013/09/11/118178.aspx
圖片還是被擋掉
看不到圖片
神奇的是
在原文點圖片另開啟視窗時
是可以看到圖片的