【问题标题】:Xamarin Listview groupingXamarin Listview 分组
【发布时间】:2015-10-28 23:26:20
【问题描述】:

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

[
    {"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"}
]

//来自此json源的列表视图中的9个项目

但我想要的是对某个键值的所有项目进行分组,例如"cat",并实现如下效果:

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

【问题讨论】:

    标签: android listview xamarin cross-platform xamarin.forms


    【解决方案1】:

    将您的数据分组到集合中,然后将这些集合添加到您的 ListView 中。集合需要是您自己的类,具有用于绑定组的属性。

    这是一个演练:

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

        myListView.IsGroupingEnabled = true;
        myListView.GroupDisplayBinding = new Binding("GroupKey"); // See below
    

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

        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);
            }
        }
    

    最后,分组添加数据:

        var groups = new ObservableCollection<Grouping<string, MyDataClass>>();
    
        // You can just pass a set of data in (where "GroupA" is an enumerable set)
        groups.Add(new Grouping<string, MyDataClass>("GroupA", GroupA)); 
    
        // Or filter down a set of data
        groups.Add(new Grouping<string, MyDataClass>("GroupB", 
            MyItems.Where(a => a.SomeFilter())));
    
        myListView.ItemSource = groups;
    

    像以前一样将您的单元格绑定到 MyDataClass:

        var cell = new DataTemplate(typeof(TextCell));
        cell.SetBinding(TextCell.TextProperty, "SomePropertyFromMyDataClass");
        cell.SetBinding(TextCell.DetailProperty, "OtherPropertyFromMyDataClass");
        myListView.ItemTemplate = cell;
    

    查看它以了解为什么在 Grouping 类中使用模板 K 而不是字符串、如何自定义标题外观等等:
    http://motzcod.es/post/94643411707/enhancing-xamarinforms-listview-with-grouping

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

    【讨论】:

      【解决方案2】:

      在我的环境中,此 url http://motzcod.es/post/94643411707/enhancing-xamarinforms-listview-with-grouping 中的代码不起作用。

      不起作用的代码在这里

      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);
      

      所以我改了代码。

      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)));
      }
      

      你可以这样看。

      [https://i.stack.imgur.com/BswPq.png][1]

      这是我所有的脚本

      项目是合作伙伴

      Item.cs

      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();
                  }
              }
          }
       }
      

      PartnersGrouping.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);
                  }
              }
          }
      }
      

      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;
                  }
              }
          }
      }
      

      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>
      

      谢谢!!

      【讨论】:

        【解决方案3】:

        Xamarin.Forms ListView 确实支持分组。请查看他们的文档http://developer.xamarin.com/guides/cross-platform/xamarin-forms/user-interface/listview/customizing-list-appearance/#Grouping 以了解如何使用它。

        【讨论】:

          猜你喜欢
          • 2019-02-15
          • 2017-05-14
          • 2020-02-07
          • 2018-01-17
          • 2021-10-10
          • 1970-01-01
          • 2018-10-23
          相关资源
          最近更新 更多