前提・実現したいこと
Xmarin.Formsを使用してアプリを開発しています。
List内にListを格納したクラスをListViewで表示したいと思っているのですが、
Jason Smith's Xamarin Forms Performance Tips の記載にあるように、
DO NOT nest ListViews. Instead, use groups within a single ListView. Nesting is explicitly unsupported and will break your application.
ListViewをネストさせるのではなく、グルーピングを使用する、となっています。
そこで、公式ドキュメント のサンプルをベースに作成を試みたのですが、うまくいきません。
どのように実装すべきか、ご教授いただきたいです。
作成したい画面のイメージ
試したこと
ListViewにバインドするデータが2階層となっているもののサンプルを作成致しました。
https://github.com/takuo-nkmr/NestedListViewSample
該当のソースは下記となります。
NestedListViewSamplePage.xaml
xml
1<?xml version="1.0" encoding="utf-8"?> 2<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 3 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 4 xmlns:local="clr-namespace:NestedListViewSample" 5 x:Class="NestedListViewSample.NestedListViewSamplePage" 6 Title="Nested ListView Sample"> 7 <ListView x:Name="ItemDataList" 8 HasUnevenRows="True" 9 SeparatorColor="Transparent" 10 IsGroupingEnabled="True"> 11 <ListView.GroupHeaderTemplate> 12 <DataTemplate> 13 <ViewCell> 14 <StackLayout> 15 <Label FontSize="20" FontAttributes="Bold" 16 Text="{Binding Key.FirstItemName}"/> 17 <Image Source="drawable/test_img.png" 18 HorizontalOptions="Start" 19 HeightRequest="50"/> 20 </StackLayout> 21 </ViewCell> 22 </DataTemplate> 23 </ListView.GroupHeaderTemplate> 24 <ListView.ItemTemplate> 25 <DataTemplate> 26 <ViewCell> 27 <StackLayout> 28 <Label Text="{Binding SecondItemName}"/> 29 </StackLayout> 30 </ViewCell> 31 </DataTemplate> 32 </ListView.ItemTemplate> 33 </ListView> 34</ContentPage>
コードビハインド
c#
1using System; 2using System.Collections.Generic; 3using System.Collections.ObjectModel; 4using NestedListViewSample.Model; 5using Xamarin.Forms; 6 7namespace NestedListViewSample 8{ 9 public partial class NestedListViewSamplePage : ContentPage 10 { 11 ObservableCollection<Grouping<ItemModel, SecondItem>> Itemist { get; set; } = 12 new ObservableCollection<Grouping<ItemModel, SecondItem>>(); 13 14 public NestedListViewSamplePage() 15 { 16 InitializeComponent(); 17 18 for (var i = 0; i < 30; i++) 19 { 20 // 1階層目セット 21 var itemData = new ItemModel() 22 { 23 FirstItemName = "アイテム名 1 - " + i.ToString() 24 }; 25 26 // 2階層目セット 27 var secondItemList = new List<SecondItem>(); 28 for (var j = 0; j < 3; j++) 29 { 30 secondItemList.Add(new SecondItem 31 { 32 SecondItemName = "アイテム名 2 - " + j.ToString() 33 }); 34 } 35 itemData.SecondItems = secondItemList; 36 37 var group = new Grouping<ItemModel, SecondItem>(itemData, itemData.SecondItems); 38 39 Itemist.Add(group); 40 } 41 ItemDataList.ItemsSource = Itemist; 42 } 43 } 44 45 public class Grouping<K, T> : ObservableCollection<T> 46 { 47 public K Key { get; private set; } 48 49 public Grouping(K key, IEnumerable<T> items) 50 { 51 Key = key; 52 foreach (var item in items) 53 this.Items.Add(item); 54 } 55 } 56} 57
モデルクラス
c#
1using System; 2using System.Collections.Generic; 3 4namespace NestedListViewSample.Model 5{ 6 public class ItemModel 7 { 8 public string FirstItemName { get; set; } 9 public List<SecondItem> SecondItems { get; set; } 10 } 11 12 public class SecondItem 13 { 14 public string SecondItemName { get; set; } 15 } 16} 17
上記のようなグループ構成としてはみたものの、GroupHeaderで1行、Itemで1行(ソースでは固定で3行)と
なってしまいます。
Header + Item全部を1行として、ListViewで選択可能としたいです。
(このために、別で全てをItemに格納して表示させてみたのですが、今度はItemModel.SecondItemの内容が
表示できず・・・)
実現したいこと
- ItemModelクラスの1つをListViewの1行として表示したいです。
- SecondItemクラスの内容全てを1行の中の要素として表示したいです。
補足情報(FW/ツールのバージョンなど)
- Visual Studio for Mac 7.4.3
- Xamarin.Forms 2.5.0.121934
- 検証端末: Nexus7(Android6.0.1)
iPad Air2(iOS11.3)