ホーム > Expression Blend > Windows Phone 7 のはてなフォトライフビューワを作る

Windows Phone 7 のはてなフォトライフビューワを作る (前編)

伊勢 シン@スマートフォン勉強会[著], わにちゃん@ExpressionTech.jp[編集]

はてなフォトライフからデータを取得するプログラムを書く

ソリューションエクスプローラから MainPage.xaml.cs を開いてください。こんな感じになってると思います。

public partial class MainPage : PhoneApplicationPage
{
    // Constructor
    public MainPage()
    {
        InitializeComponent();

        // Set the data context of the listbox control to the sample data
        DataContext = App.ViewModel;
        this.Loaded += new RoutedEventHandler(MainPage_Loaded);
    }

    // Load data for the ViewModel Items
    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        if (!App.ViewModel.IsDataLoaded)
        {
            App.ViewModel.LoadData();
        }
    }
}

はてなフォトライフからデータを持ってくる処理は僕が以前書いたことがあり、Gistに書いてあるのでコピペしてきます。

https://gist.github.com/492486

これはLINQPad用の書き殴りなので、使いやすいようにメソッドにしようと思います。まず、結果が匿名型になっていてバインディングできないので、結果を格納するためのクラスを作ります。プロジェクト右クリック→Add→New Item です。

f:id:iseebi:20110307034024p:image

Classを選んでHatenaFotolifeRssItem.csと名前をつけてAddをクリックします。

f:id:iseebi:20110307034025p:image

新しいファイルができるので、元のソースに書いてあった戻り値を全部パブリックプロパティにします。

public class HatenaFotolifeRssItem
{
    public string Title { get; set; }
    public string Link { get; set; }
    public string Description { get; set; }
    public string Content { get; set; }
    public string Date { get; set; }
    public string ImageUrl { get; set; }
    public string ImageUrlSmall { get; set; }
    public string ImageUrlMedium { get; set; }
    public string Syntax { get; set; }
    public string[] Colors { get; set; }
}

できたら、MainPage.xaml.cs へ戻ります。Gistのソースから const の4行をフィールドとしてコピペします。次に、XDocument docを宣言しているところから、次のLINQまでをコピペして、以下のようなメソッドを作ります。

select new で匿名型を作っているところは、 HatenaFotolifeRssItem() を書き足して先ほど作ったクラスが作られるように変更します。また、最後のColorsのところは匿名型から通常の型にした影響でキャストが必要になっていますので、コレも追加しています。

さらに、XDocumentの読み込み先URLもパラメータにしました。

        public void LoadImageListBox(string url, ListBox targetList)
        {
            XDocument doc = XDocument.Load(url);
            var q = from e in doc.Root.Elements()
                    where e.Name.ToString().EndsWith("item")
                    select new HatenaFotolifeRssItem()
                    {
                        Title = e.Element(rssSpace + "title").Value,
                        Link = e.Element(rssSpace + "link").Value,
                        Description = e.Element(rssSpace + "description").Value,
                        Content = e.Element(contentSpace + "encoded").Value,
                        Date = e.Element(dcSpace + "date").Value,
                        ImageUrl = e.Element(hatenaSpace + "imageurl").Value,
                        ImageUrlSmall = e.Element(hatenaSpace + "imageurlsmall").Value,
                        ImageUrlMedium = e.Element(hatenaSpace + "imageurlmedium").Value,
                        Syntax = e.Element(hatenaSpace + "syntax").Value,
                        //Colors = from c in e.Element(hatenaSpace + "colors").Elements() where c.Name == hatenaSpace + "color" select c.Value
                        Colors = (from c in e.Element(hatenaSpace + "colors").Elements() where c.Name == hatenaSpace + "color" select c.Value).ToArray<string>()
                    };
        }

おっと、XDocument に赤線が出ています。アセンブリの参照が足りていません。

The type or namespace name 'XDocument' could not be found (are you missing a using directive or anassembly reference?)

プロジェクトのReferencesのところを右クリック、Add References...です。

f:id:iseebi:20110307034027p:image

System.Xml.Linq を選び、OKを押します。

f:id:iseebi:20110307034028p:image

参照追加してもまだ赤線が消えませんが、スマートタグが出るようになっています。using System.Xml.Linq; を選びます。先頭行にusingが追加されて問題が解決されます。

f:id:iseebi:20110307034029p:image

次に、コンストラクタにデザインで作ったListBoxに先ほど示したRSSのURLに合わせて画像を読み込むようにメソッドの呼び出しを書きます。

// 画像の読み込み
LoadImageListBox("https://f.hatena.ne.jp/userlist?mode=rss", newPhotoListBox);
LoadImageListBox("https://f.hatena.ne.jp/hotfoto?mode=rss", hotPhotoListBox);
LoadImageListBox("https://f.hatena.ne.jp/iseebi/rss?mode=rss", userPhotoListBox);

ここまででプログラムはこんな感じになっています。

public partial class MainPage : PhoneApplicationPage
{
    const string rssSpace = "{https://purl.org/rss/1.0/}";
    const string contentSpace = "{https://purl.org/rss/1.0/modules/content/}";
    const string dcSpace = "{https://purl.org/dc/elements/1.1/}";
    const string hatenaSpace = "{https://www.hatena.ne.jp/info/xmlns#}";

    // Constructor
    public MainPage()
    {
        InitializeComponent();

        // Set the data context of the listbox control to the sample data
        DataContext = App.ViewModel;
        this.Loaded += new RoutedEventHandler(MainPage_Loaded);

        // 画像の読み込み
        LoadImageListBox("https://f.hatena.ne.jp/userlist?mode=rss", newPhotoListBox);
        LoadImageListBox("https://f.hatena.ne.jp/hotfoto?mode=rss", hotPhotoListBox);
        LoadImageListBox("https://f.hatena.ne.jp/iseebi/rss?mode=rss", userPhotoListBox);
    }

    // Load data for the ViewModel Items
    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        if (!App.ViewModel.IsDataLoaded)
        {
            App.ViewModel.LoadData();
        }
    }

    public void LoadImageListBox(string url, ListBox targetList)
    {
        XDocument doc = XDocument.Load(url);
        var q = from e in doc.Root.Elements()
                where e.Name.ToString().EndsWith("item")
                select new HatenaFotolifeRssItem()
                {
                    Title = e.Element(rssSpace + "title").Value,
                    Link = e.Element(rssSpace + "link").Value,
                    Description = e.Element(rssSpace + "description").Value,
                    Content = e.Element(contentSpace + "encoded").Value,
                    Date = e.Element(dcSpace + "date").Value,
                    ImageUrl = e.Element(hatenaSpace + "imageurl").Value,
                    ImageUrlSmall = e.Element(hatenaSpace + "imageurlsmall").Value,
                    ImageUrlMedium = e.Element(hatenaSpace + "imageurlmedium").Value,
                    Syntax = e.Element(hatenaSpace + "syntax").Value,
                    //Colors = from c in e.Element(hatenaSpace + "colors").Elements() where c.Name == hatenaSpace + "color" select c.Value
                    Colors = (from c in e.Element(hatenaSpace + "colors").Elements() where c.Name == hatenaSpace + "color" select c.Value).ToArray<string>()
                };
        targetList.ItemSource = q;
    }
}

ここまでで実行するとエラーになってしまいます。Windows Phone 7では同期処理は御法度。そういうわけでXDocument.LoadのURL指定は相対パスしか認識してくれないのです。

f:id:iseebi:20110307034045p:image

INDEX

コメント

▲このページのトップへ