iT邦幫忙

DAY 2
5

Windows Phone 程式開發系列 第 2

[WP 開發] 讀取 facebook 粉絲團 RSS

本篇文章將撰寫一個應用程式,抓取【微軟最有價值專家 Microsoft MVP 台灣粉絲團】RSS 中的資料 Title、Links、PublishDate,經過資料整理與分析後顯示於 Windows Phone App 中。


本文刊載於
http://www.dotblogs.com.tw/chou/archive/2013/09/11/118178.aspx

在這篇文章您可以學到:

  1. 了解 facebook 的 RSS 網址如何取得。
  2. 撰寫基本的 Windows Phone App。
  3. 了解 Windows Phone 專案範本的程式結構。
  4. 下載網路資料,解析後顯示在畫面中。

取得【微軟最有價值專家 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


上一篇
[WP 開發] 使用 Windows Phone App Studio 建立 App
下一篇
[WP 開發] Converter 綁定值轉換
系列文
Windows Phone 程式開發27
0
海綿寶寶
iT邦大神 1 級 ‧ 2013-09-17 07:36:25

在這裡貼文
被 dotblogs 擋外連圖片就算了

沒想到看原文
http://www.dotblogs.com.tw/chou/archive/2013/09/11/118178.aspx
圖片還是被擋掉
看不到圖片
無言

神奇的是
在原文點圖片另開啟視窗時
是可以看到圖片的
XD

0
kradark
iT邦好手 1 級 ‧ 2013-09-17 07:43:10

換個圖床吧
鎖refer了吧

我要留言

立即登入留言