Android Xamarin列表视图分组

Android Xamarin列表视图分组,android,listview,xamarin,cross-platform,xamarin.forms,Android,Listview,Xamarin,Cross Platform,Xamarin.forms,我正在处理xamarin.froms中的列表视图。我可以为每个记录轻松地在listview中填充listitem: [ {"cat":1, "name":"alpha"}, {"cat":1, "name":"beta"}, {"cat":1, "name":"gamma"}, {"cat":2, "name":"john"}, {"cat":2, "name":"william"}, {"cat":2, "name":"smith"},

我正在处理xamarin.froms中的列表视图。我可以为每个记录轻松地在listview中填充listitem:

[
    {"cat":1, "name":"alpha"},
    {"cat":1, "name":"beta"},
    {"cat":1, "name":"gamma"},
    {"cat":2, "name":"john"},
    {"cat":2, "name":"william"},
    {"cat":2, "name":"smith"},
    {"cat":2, "name":"steve"},
    {"cat":3, "name":"abc"},
    {"cat":3, "name":"xyz"}
]
//listview中的9项来自此json源

但我想要的是将所有项目分组到某个键值上,在这里说
“cat”
,并实现如下功能:


任何对此的建议或方法都将不胜感激。

Xamarin.Forms ListView支持分组。请查看他们的文档以了解如何使用它。

将数据分组到集合中,并将这些集合添加到ListView中。集合必须是您自己的类,并具有用于将组与绑定的属性

这里有一个演练:

在ListView上设置分组,包括将每个组绑定到的属性,在本例中为“GroupKey”

然后分组添加数据(例如列表列表)。这通常意味着您需要创建自己的类来显示分组,例如:

    public class Grouping<K, T> : ObservableCollection<T>
    {
        // NB: This is the GroupDisplayBinding above for displaying the header
        public K GroupKey { get; private set; } 

        public Grouping(K key, IEnumerable<T> items)ac
        {
            GroupKey = key;
            foreach (var item in items)
                this.Items.Add(item);
        }
    }
查看它,了解有关为什么在
分组
类中使用模板
K
而不是字符串的解释,以及如何自定义标题外观等:


(归功于@pnavk答案中的链接)

在我的环境中,代码在此url中不起作用

不起作用的代码在这里

var partnersSorted = from item in Partners
         orderby item.UserName
         group item by item.UserNameSort into PartnersGroup
         select new Grouping<string, Monkey>(PartnersGroup.Key, PartnersGroup);

MonkeysGrouped = new ObservableCollection<Grouping<string, Monkey>>(partnersSorted);
PartnersGroup.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace NewHeats.Models
{
    public class PartnersGrouping<K,T> : ObservableCollection<T>
    {
        public K Key { get; private set; }

        public PartnersGrouping(K key,IEnumerable<T> items)
        {
            Key = key;
            foreach (var item in items)
            {
                this.Items.Add(item);
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
名称空间NewHeats.Models
{
公共类合作伙伴组:ObservableCollection
{
公钥{get;private set;}
公共合作伙伴分组(K键,IEnumerable项)
{
钥匙=钥匙;
foreach(项目中的var项目)
{
此.Items.Add(item);
}
}
}
}
PartnersViewModel.cs

using System;
using System.Windows.Input;
using System.ComponentModel;
using System.Collections.ObjectModel;
using Xamarin.Forms;
using NewHeats.Models;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Linq;
using System.Diagnostics.Contracts;

namespace NewHeats.ViewModels
{
    public class PartnersViewModel : BaseViewModel
    {
        public Item Me
        {
            get;
            set;
        }
        public ObservableCollection<Item> Partners { get; set; }
        public ObservableCollection<PartnersGrouping<string, Item>> PartnersGrouped { get; set; }
        public Item SelectedPartner { get; set; }
        public Command LoadPartnersCommand { get; set; }
        public PartnersViewModel()
        {
            Title = "Partners";
            Partners = new ObservableCollection<Item>();
            PartnersGrouped = new ObservableCollection<PartnersGrouping<string, Item>>();
            LoadPartnersCommand = new Command(async() =>await ExecuteLoadPartnersCommand());
        }

        async Task ExecuteLoadPartnersCommand()
        {
            Contract.Ensures(Contract.Result<Task>() != null);
            if (IsBusy)
                return;
            IsBusy = true;
            try
            {
                Me = await MockUsrDataStore.GetItemAsync("naoto");                           
                Partners.Clear();
                var allfriends = await MockFriDataStore.GetItemsAsync(true);                 
                var myFriends = allfriends.Where(x => x.MyId == Me.Id);                      
                var allUsers = await MockUsrDataStore.GetItemsAsync(true);                   

                foreach (var item in myFriends)
                {
                    var partner = allUsers.FirstOrDefault(x => x.Id == item.FriendId);       
                    if (partner!=null)
                    {
                        Partners.Add(partner);
                    }
                }
                var sortedpartners = Partners.OrderBy(x => x.UserName).GroupBy(y => y.UserNameSort);
                foreach (var item in sortedpartners)
                {
                     PartnersGrouped.Add(new PartnersGrouping<string, Item>(item.Key, Partners.Where(x=>x.UserNameSort == item.Key)));
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
            finally
            {
                IsBusy = false;
            }
        }
    }
}
使用系统;
使用System.Windows.Input;
使用系统组件模型;
使用System.Collections.ObjectModel;
使用Xamarin.Forms;
使用NewHeats.Models;
使用System.Threading.Tasks;
使用系统诊断;
使用System.Linq;
使用System.Diagnostics.Contracts;
名称空间NewHeats.ViewModels
{
公共类PartnersViewModel:BaseViewModel
{
公共物品
{
得到;
设置
}
公共可观测集合伙伴{get;set;}
公共ObservableCollection合作伙伴分组{get;set;}
公共项SelectedPartner{get;set;}
公共命令LoadPartnersCommand{get;set;}
公共合作伙伴可视模型()
{
Title=“合伙人”;
Partners=新的ObservableCollection();
PartnersGroup=新的ObservableCollection();
LoadPartnersCommand=new命令(async()=>await ExecuteLoadPartnersCommand());
}
异步任务执行器ADPARTNERSCOMAND()
{
Contract.sure(Contract.Result()!=null);
如果(忙)
返回;
IsBusy=true;
尝试
{
Me=wait MockUsrDataStore.GetItemAsync(“naoto”);
Partners.Clear();
var allfriends=wait MockFriDataStore.GetItemsAsync(true);
var myFriends=allfriends.Where(x=>x.MyId==Me.Id);
var allUsers=await MockUsrDataStore.GetItemsAsync(true);
foreach(myFriends中的变量项)
{
var partner=allUsers.FirstOrDefault(x=>x.Id==item.FriendId);
if(partner!=null)
{
合作伙伴。添加(合作伙伴);
}
}
var sortedpartners=Partners.OrderBy(x=>x.UserName).GroupBy(y=>y.UserNameSort);
foreach(分类合作伙伴中的var项目)
{
添加(新的PartnersGroup(item.Key,Partners.Where(x=>x.UserNameSort==item.Key));
}
}
捕获(例外情况除外)
{
Debug.WriteLine(ex);
}
最后
{
IsBusy=false;
}
}
}
}
PartnerPage.xaml

<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="NewHeats.Views.PartnersPage" xmlns:vm="clr-namespace:NewHeats.ViewModels" xmlns:controls="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin" Title="{Binding Title}">
    <ContentPage.Resources>
        <ResourceDictionary>
            <!--Page Level Resources: Compatibile with Xamarin Live Player -->
            <Color x:Key="Primary">#2196F3</Color>
            <Color x:Key="Accent">#96d1ff</Color>
            <Color x:Key="LightTextColor">#999999</Color>
        </ResourceDictionary>
    </ContentPage.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <ScrollView Grid.Row="0">
            <StackLayout Orientation="Vertical" Padding="16,40,16,40" Spacing="10">
                <ListView ItemsSource="{Binding PartnersGrouped}"
                          HasUnevenRows="true"
                          VerticalOptions="FillAndExpand"
                          IsPullToRefreshEnabled="true"
                          CachingStrategy="RecycleElement"
                          IsRefreshing="{Binding IsBusy, Mode=OneWay}"
                          RefreshCommand="{Binding LoadPartnersCommand}"
                          ItemSelected="Handle_ItemSelected"
                          SelectedItem="{Binding SelectedPartner}"
                          GroupDisplayBinding="{Binding Key}"
                          IsGroupingEnabled="true"
                          GroupShortNameBinding="{Binding Key}">
                    <ListView.GroupHeaderTemplate>
                        <DataTemplate>
                            <ViewCell Height="25">
                                <StackLayout VerticalOptions="FillAndExpand"
                                             Padding="5"
                                             BackgroundColor="#3498DB">
                                       <Label Text="{Binding Key}" TextColor="White" VerticalOptions="Center"/>
                                </StackLayout>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.GroupHeaderTemplate>
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <Grid>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="60"/>
                                    </Grid.RowDefinitions>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="60"/>
                                        <ColumnDefinition Width="*"/>
                                    </Grid.ColumnDefinitions>
                                    <controls:CircleImage Source="husky.jpg"
                                                          Aspect="AspectFill"
                                                          Grid.Column="0"
                                                          Grid.Row="0"
                                                          WidthRequest="60"
                                                          HeightRequest="60">
                                    </controls:CircleImage>
                                       <StackLayout Orientation="Vertical" Grid.Column="1">
                                           <Label Text="{Binding UserName}" VerticalTextAlignment="Center"/>
                                      </StackLayout>
                                </Grid>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </StackLayout>
        </ScrollView>
    </Grid>
</ContentPage>

#2196F3
#96d1ff
#999999
谢谢

var sortedPartners = Partners.OrderBy(x => x.UserName).GroupBy(y => y.UserNameSort);
foreach (var item in sortedPartners)
{
     PartnersGrouped.Add(new PartnersGrouping<string, Item>(item.Key, Partners.Where(x=>x.UserNameSort == item.Key)));
}
using System;

namespace NewHeats.Models
{
    public class Item
    {
        public string Id
        {
            get;
            set;
        }
        public string UserName
        {
            get;
            set;
        }
        public DateTime RegisterDate
        {
            get;
            set;
        }
        public string Field
        {
            get;
            set;
        }
        public string Password
        {
            get;
            set;
        }
        public int Heats
        {
            get;
            set;
        }
        public string UserNameSort
        {
             get
            {
                 if (string.IsNullOrWhiteSpace(UserName) || UserName.Length == 0)
                    return "?";

                 return UserName[0].ToString().ToUpper();
            }
        }
    }
 }
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace NewHeats.Models
{
    public class PartnersGrouping<K,T> : ObservableCollection<T>
    {
        public K Key { get; private set; }

        public PartnersGrouping(K key,IEnumerable<T> items)
        {
            Key = key;
            foreach (var item in items)
            {
                this.Items.Add(item);
            }
        }
    }
}
using System;
using System.Windows.Input;
using System.ComponentModel;
using System.Collections.ObjectModel;
using Xamarin.Forms;
using NewHeats.Models;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Linq;
using System.Diagnostics.Contracts;

namespace NewHeats.ViewModels
{
    public class PartnersViewModel : BaseViewModel
    {
        public Item Me
        {
            get;
            set;
        }
        public ObservableCollection<Item> Partners { get; set; }
        public ObservableCollection<PartnersGrouping<string, Item>> PartnersGrouped { get; set; }
        public Item SelectedPartner { get; set; }
        public Command LoadPartnersCommand { get; set; }
        public PartnersViewModel()
        {
            Title = "Partners";
            Partners = new ObservableCollection<Item>();
            PartnersGrouped = new ObservableCollection<PartnersGrouping<string, Item>>();
            LoadPartnersCommand = new Command(async() =>await ExecuteLoadPartnersCommand());
        }

        async Task ExecuteLoadPartnersCommand()
        {
            Contract.Ensures(Contract.Result<Task>() != null);
            if (IsBusy)
                return;
            IsBusy = true;
            try
            {
                Me = await MockUsrDataStore.GetItemAsync("naoto");                           
                Partners.Clear();
                var allfriends = await MockFriDataStore.GetItemsAsync(true);                 
                var myFriends = allfriends.Where(x => x.MyId == Me.Id);                      
                var allUsers = await MockUsrDataStore.GetItemsAsync(true);                   

                foreach (var item in myFriends)
                {
                    var partner = allUsers.FirstOrDefault(x => x.Id == item.FriendId);       
                    if (partner!=null)
                    {
                        Partners.Add(partner);
                    }
                }
                var sortedpartners = Partners.OrderBy(x => x.UserName).GroupBy(y => y.UserNameSort);
                foreach (var item in sortedpartners)
                {
                     PartnersGrouped.Add(new PartnersGrouping<string, Item>(item.Key, Partners.Where(x=>x.UserNameSort == item.Key)));
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
            finally
            {
                IsBusy = false;
            }
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="NewHeats.Views.PartnersPage" xmlns:vm="clr-namespace:NewHeats.ViewModels" xmlns:controls="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin" Title="{Binding Title}">
    <ContentPage.Resources>
        <ResourceDictionary>
            <!--Page Level Resources: Compatibile with Xamarin Live Player -->
            <Color x:Key="Primary">#2196F3</Color>
            <Color x:Key="Accent">#96d1ff</Color>
            <Color x:Key="LightTextColor">#999999</Color>
        </ResourceDictionary>
    </ContentPage.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <ScrollView Grid.Row="0">
            <StackLayout Orientation="Vertical" Padding="16,40,16,40" Spacing="10">
                <ListView ItemsSource="{Binding PartnersGrouped}"
                          HasUnevenRows="true"
                          VerticalOptions="FillAndExpand"
                          IsPullToRefreshEnabled="true"
                          CachingStrategy="RecycleElement"
                          IsRefreshing="{Binding IsBusy, Mode=OneWay}"
                          RefreshCommand="{Binding LoadPartnersCommand}"
                          ItemSelected="Handle_ItemSelected"
                          SelectedItem="{Binding SelectedPartner}"
                          GroupDisplayBinding="{Binding Key}"
                          IsGroupingEnabled="true"
                          GroupShortNameBinding="{Binding Key}">
                    <ListView.GroupHeaderTemplate>
                        <DataTemplate>
                            <ViewCell Height="25">
                                <StackLayout VerticalOptions="FillAndExpand"
                                             Padding="5"
                                             BackgroundColor="#3498DB">
                                       <Label Text="{Binding Key}" TextColor="White" VerticalOptions="Center"/>
                                </StackLayout>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.GroupHeaderTemplate>
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <Grid>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="60"/>
                                    </Grid.RowDefinitions>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="60"/>
                                        <ColumnDefinition Width="*"/>
                                    </Grid.ColumnDefinitions>
                                    <controls:CircleImage Source="husky.jpg"
                                                          Aspect="AspectFill"
                                                          Grid.Column="0"
                                                          Grid.Row="0"
                                                          WidthRequest="60"
                                                          HeightRequest="60">
                                    </controls:CircleImage>
                                       <StackLayout Orientation="Vertical" Grid.Column="1">
                                           <Label Text="{Binding UserName}" VerticalTextAlignment="Center"/>
                                      </StackLayout>
                                </Grid>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </StackLayout>
        </ScrollView>
    </Grid>
</ContentPage>