Windows Phone 開發 - 讀取【微軟最有價值專家 Microsoft MVP 台灣粉絲團】RSS

  • 1888
  • 0
  • 2013-09-12

Windows Phone 開發 - 讀取【微軟最有價值專家 Microsoft MVP 台灣粉絲團】RSS

 

程式功能

我想要抓【微軟最有價值專家 Microsoft MVP 台灣粉絲團】RSS 中的資料 Title、Links、PublishDate 做顯示。

 

取得【微軟最有價值專家 Microsoft MVP 台灣粉絲團】RSS 網址

連結至粉絲團網址 https://www.facebook.com/twmvp,隨意點選任意照片,取得 ID 為 215783948459346

image

 

RSS 網址為 https://www.facebook.com/feeds/page.php?format=atom10&id=上述步驟取得的 ID

組合後的網址 https://www.facebook.com/feeds/page.php?format=atom10&id=215783948459346

 

程式開發

新增專案,在此我使用樞紐分析應用程式,名稱為 MvpRssPhoneApp,使用樞紐分析應用程式的原因是他有現成的 MVVM 架構,方便初學者學習。

SNAGHTML657311

 

先開啟 ItemViewModel.cs

image

 

修改 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 設計畫面

image

 

在 StackPanel 內的顯示內容有兩個 TextBlock。

image

 

                            <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

image

 

在 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;
        }

 

執行看看,有資料了

SNAGHTMLdc064b

 

接著,我們替換真實資料,修改 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

SNAGHTMLdf8eb6

 

加入時可能有警告視窗,請按是

SNAGHTMLdfc2b7

 

加入完成

image

 

撰寫 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() 載入資料。

image

 

執行結果,Tilte 的資料看起來像是亂碼。

SNAGHTMLe655e1

 

我們透過 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()
                    }
                );
                }
            });
        }

 

重新執行,可顯示粉絲團上的資料。

SNAGHTMLe802b6

 

範例下載

MvpRssPhoneApp.zip

 

其他相關資訊

How to create a basic RSS reader for Windows Phone