こんにちは。エクセルソフトの田淵です。
ListView に動的に値を追加する方法をご紹介します。
2015/8/27
Xamarin.Forms で ListView を最後まで表示するとクルクルを表示してその間に処理をするには~その1~ - Xamarin 日本語情報
Xamarin.Forms で ListView を最後まで表示するとクルクルを表示してその間に処理をするには~その2~ - Xamarin 日本語情報
を追記しました。
ListView については Xamarin 公式ページの Working with ListView を一通り読んでいただきたいのですが、注意点というかハマりポイントが分かりましたので共有します。(WPF をやられている皆さんは周知の事実っぽいのが泣けますが)
ListView には ItemsSource
と ItemTemplate (任意)
を指定します。ItemsSource には 配列
や List<T>
, ObservableCollection<T>
などを使用できます。私はご覧のとおりズブの素人のため List を主に使っていました。
上記の公式ページで
The above approach will populate the ListView with a list of strings. By default, ListView will call ToString and display the result in a TextCell for each row. To customize how data is displayed, see Cell Appearance.
Because ItemsSource has been sent to an array, the content will not update as the underlying list or array changes. If you want the ListView to automatically update as items are added, removed and changed in the underlying list, you'll need to use an ObservableCollection. ObservableCollection is defined in System.Collection.ObjectModel and is just like List, except that it can notify ListView of any changes:
とあるように、ListView をアップデートする必要がある場合は INotifyCollectionChanged が実装されている(@espresso3389 さんありがとうございます!) ObservableCollection
を使いなさいということみたいです。
動きのサンプル
サンプルコード
使い方(ListView の用意)
ということで前置きが長くなりましたが、使い方です。
まずは ListView を用意します。
C#:
// ListView のセルを定義します。 var cell = new DataTemplate(typeof(TextCell)); cell.SetBinding(TextCell.TextProperty, "TextItem"); cell.SetBinding(TextCell.DetailProperty, "DetailItem"); // ListView を定義します。 var list = new ListView { ItemsSource = listItems, ItemTemplate = cell, };
XAML:
<ListView x:Name="list" ItemsSource="{Binding}"> <ListView.ItemTemplate> <DataTemplate> <TextCell Text="{Binding TextItem}" Detail="{Binding DetailItem}" /> </DataTemplate> </ListView.ItemTemplate> </ListView>
XAML のコードビハインドには this.BindingContext = listItems;
を定義しておきます。
で、この ItemsSource の listItems を ObservableCollection で用意します。今回はサンプルなのでデータを順次追加してます。
using System.Collections.ObjectModel; ObservableCollection<ListItem> listItems = new ObservableCollection<ListItem>();
void AddListItem(int i) { foreach (var j in Enumerable.Range(i, cellAmount)) { listItems.Add(new ListItem { TextItem = "TextData " + j, DetailItem = "DetailData " + j }); } }
使い方 (ItemAppearing のイベントハンドラーを用意)
ListView の ItemAppearing イベントは ListView の各 Item が表示された時に発生するイベントです。ここに、例えば listItems.Last() == e.Item as ListItem
など最後が表示された時にデータを追加する処理を記述すれば OK です。後は(多分 ObservableCollection が ListView に NotifyChanged して) ListView が勝手に表示を更新してくれます。
list.ItemAppearing += (object sender, ItemVisibilityEventArgs e) => { // ObservableCollection の最後が ListView の Item と一致した時に ObservableCollection にデータを追加する処理を行いましょう。 if (listItems.Last() == e.Item as ListItem) { // ObservableCollection にデータを追加する処理 // ここでは n をインクリメントして cellAmount の 25 ずつデータを追加しています。 n++; AddListItem(cellAmount * n); } };
Twitter クライアントとかインターネットから Json を引っ張ってくるようなアプリではよく使う手法になるかと思います。
ちなみにですが、List<T> で ItemsSource を用意した場合は、List<T> を更新した後で、ItemsSource を再指定して、再度
ItemTemplate = new DataTemplate(typeof(
して手動で ListView に更新を伝える必要があります。ちょっと面倒なのでなるべくObservableCollection
を使いたいですね。
Xamarin 気になった方は
いかがでしょうか。こんな簡単に Twitter とかでよく見るアレが実装できるなんて素晴らしいですね!笑
是非 ダウンロード(直接) / ダウンロード(弊社経由) して触ってみてください。 学習用リソース や JXUG リンクページ に参考資料を纏めてますので併せてどうぞ。
Xamarin の情報が欲しい方はこのブログも購読いただいたりすると嬉しいです。
以上です。