UWPアプリでコンパイル時バインド(x:Bind)を使ってListViewに値を表示する

  • 8
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

MVVMパターンなどでViewとロジックを切り離すためのコアとなってくる技術のひとつであるXAMLのバインド。正直初めて目にしたときはなにかと思いましたし、今でも何か慣れない感があるのですが、それでも少しずつ使えるようになってきました。今回は実行時バインドである{Binding ...}ではなく、実行時のバインドである{x:Bind ...}を使って、コードビハインドで定義されているコレクションの中身をListViewに表示させてみます。

コードビハインドは以下のような感じになっていて、ボタンをクリックするとPopularTagsコレクションに値が埋められます。このとき、コードビハインドには如何なるUIの名前も出てきてないところがポイントです。

public sealed partial class MainPage : Page
{
    public ObservableCollection<App1.Tag> PopularTags { get; } = new ObservableCollection<App1.Tag>();

    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        string url = @"https://qiita.com/api/v2/tags?page=1&per_page=30&sort=count";
        Uri uri = null;
        if (!Uri.TryCreate(url, UriKind.Absolute, out uri))
        {
            throw new Exception("Invalid URL");
        }

        HttpClient httpClient = new HttpClient();
        HttpResponseMessage response = await httpClient.GetAsync(uri);

        string jsonResponse = response.Content.ToString();
        JsonArray jsonArray = JsonArray.Parse(jsonResponse);
        PopularTags.Clear();
        for (uint i = 0; i < jsonArray.Count; i++)
        {
            JsonObject jsonObject = jsonArray.GetObjectAt(i);
            uint followerCount = (uint)(jsonObject.GetNamedValue("followers_count").GetNumber());
            string id = jsonObject.GetNamedString("id");
            string iconUrl = jsonObject.GetNamedString("icon_url");
            uint itemCount = (uint)(jsonObject.GetNamedValue("items_count").GetNumber());

            Tag t = new App1.Tag()
            {
                FollowerCount = followerCount,
                Id = id,
                IconUrl = iconUrl,
                ItemCount = itemCount
            };
            PopularTags.Add(t);
        }
    }
}

public class Tag
{
    public uint FollowerCount { get; set; }
    public string IconUrl { get; set; }
    public string Id { get; set; }
    public uint ItemCount { get; set; }
}    

対応してListViewは以下のように定義します。

<ListView x:Name="MainListView"
            ItemsSource="{x:Bind PopularTags}">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="local:Tag">
            <StackPanel>
                <TextBlock Text="{x:Bind Id, Mode=OneWay}" />
                <Image Source="{x:Bind IconUrl, Mode=OneWay}" />
                <TextBlock Text="{x:Bind FollowerCount, Mode=OneWay}" />
                <TextBlock Text="{x:Bind ItemCount, Mode=OneWay}" />
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

以下のようにバインドした値に合わせて各ListViewItemが表示されました。

ListView.jpg