在 CollectionView 中显示分组数据
在持续滚动的列表中显示时,大型数据集通常会变得笨拙。 在此方案中,将数据组织成组可以简化数据导航,从而改善用户体验。
.NET Multi-platform App UI (.NET MAUI) CollectionView 支持显示分组数据,并定义以下属性来控制数据的呈现方式:
IsGrouped
,类型为bool
,指示是否应在组中显示基础数据。 此属性的默认值为false
。GroupHeaderTemplate
,类型为 DataTemplate,每个组的页眉要使用的模板。GroupFooterTemplate
,类型为 DataTemplate,每个组的页脚要使用的模板。
所有这些属性都由 BindableProperty 对象提供支持,这意味着这些属性可以作为数据绑定的目标。
以下屏幕截图显示了展示分组数据的 CollectionView:
有关数据模板的详细信息,请参阅数据模板。
为数据分组
必须先对数据进行分组,然后才能显示数据。 这可以通过创建组列表来实现,其中每个组都是项列表。 组列表应为 IEnumerable<T>
集合,其中 T
定义两条数据:
- 组名称。
- 定义组内项的
IEnumerable
集合。
因此,分组数据的过程为:
- 创建对单个项建模的类型。
- 创建对单个项组建模的类型。
- 创建
IEnumerable<T>
集合,其中T
为对单个项组建模的类型。 此集合是组的集合,用于存储分组数据。 - 将数据添加到
IEnumerable<T>
集合。
示例
对数据分组时,第一步是创建对单个项进行建模的类型。 以下示例显示示例应用程序中的 Animal
类:
public class Animal
{
public string Name { get; set; }
public string Location { get; set; }
public string Details { get; set; }
public string ImageUrl { get; set; }
}
Animal
类对单个项建模。 然后,可以创建对项组建模的类型。 以下示例显示示例应用程序中的 AnimalGroup
类:
public class AnimalGroup : List<Animal>
{
public string Name { get; private set; }
public AnimalGroup(string name, List<Animal> animals) : base(animals)
{
Name = name;
}
}
AnimalGroup
类继承自 List<T>
类,并添加表示组名的 Name
属性。
然后,可以创建 IEnumerable<T>
组集合:
public List<AnimalGroup> Animals { get; private set; } = new List<AnimalGroup>();
此代码定义名为 Animals
的集合,其中集合中的每个项都是一个 AnimalGroup
对象。 每个 AnimalGroup
对象都包含名称和定义组中 Animal
对象的 List<Animal>
集合。
然后,可将分组数据添加到 Animals
集合中:
Animals.Add(new AnimalGroup("Bears", new List<Animal>
{
new Animal
{
Name = "American Black Bear",
Location = "North America",
Details = "Details about the bear go here.",
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/0/08/01_Schwarzbär.jpg"
},
new Animal
{
Name = "Asian Black Bear",
Location = "Asia",
Details = "Details about the bear go here.",
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG/180px-Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG"
},
// ...
}));
Animals.Add(new AnimalGroup("Monkeys", new List<Animal>
{
new Animal
{
Name = "Baboon",
Location = "Africa & Asia",
Details = "Details about the monkey go here.",
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
},
new Animal
{
Name = "Capuchin Monkey",
Location = "Central & South America",
Details = "Details about the monkey go here.",
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Capuchin_Costa_Rica.jpg/200px-Capuchin_Costa_Rica.jpg"
},
new Animal
{
Name = "Blue Monkey",
Location = "Central and East Africa",
Details = "Details about the monkey go here.",
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/BlueMonkey.jpg/220px-BlueMonkey.jpg"
},
// ...
}));
此代码在 Animals
集合中创建两个组。 第一个 AnimalGroup
名为 Bears
,包含熊详细信息的 List<Animal>
集合。 第二个 AnimalGroup
名为 Monkeys
,包含猴子详细信息的 List<Animal>
集合。
显示分组数据
如果数据已正确分组,CollectionView 将通过将 IsGrouped
属性设置为 true
来显示分组数据:
<CollectionView ItemsSource="{Binding Animals}"
IsGrouped="true">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
...
<Image Grid.RowSpan="2"
Source="{Binding ImageUrl}"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold" />
<Label Grid.Row="1"
Grid.Column="1"
Text="{Binding Location}"
FontAttributes="Italic"
VerticalOptions="End" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
等效 C# 代码如下:
CollectionView collectionView = new CollectionView
{
IsGrouped = true
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");
// ...
通过将 CollectionView.ItemTemplate
属性设置为 DataTemplate 来定义 CollectionView 中每个项的外观。 有关详细信息,请参阅定义项外观。
注意
默认情况下,CollectionView 将在组页眉和页脚中显示组名称。 可以通过自定义组页眉和组页脚来更改此行为。
自定义组页眉
通过将 CollectionView.GroupHeaderTemplate
属性设置为 DataTemplate,即可自定义每个组页眉的外观:
<CollectionView ItemsSource="{Binding Animals}"
IsGrouped="true">
...
<CollectionView.GroupHeaderTemplate>
<DataTemplate>
<Label Text="{Binding Name}"
BackgroundColor="LightGray"
FontSize="18"
FontAttributes="Bold" />
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
</CollectionView>
在此示例中,每个组标头都设置为显示组名的 Label,并且设置了其他外观属性。 以下屏幕截图显示了自定义组标头:
自定义组页脚
通过将 CollectionView.GroupFooterTemplate
属性设置为 DataTemplate,可以自定义每个组页脚的外观:
<CollectionView ItemsSource="{Binding Animals}"
IsGrouped="true">
...
<CollectionView.GroupFooterTemplate>
<DataTemplate>
<Label Text="{Binding Count, StringFormat='Total animals: {0:D}'}"
Margin="0,0,0,10" />
</DataTemplate>
</CollectionView.GroupFooterTemplate>
</CollectionView>
在此示例中,每个组页脚都设置为 Label,显示组中的项目数。 以下屏幕截图显示了自定义的组页脚:
空组
当 CollectionView 显示分组数据时,它将显示任何空分组。 此类组将显示一个组标头和页脚,指示该组为空。 以下屏幕截图显示了一个空组:
注意
在 iOS 10 上,空组的组标头和页脚可能全部显示在 CollectionView 顶部。
没有模板的组
CollectionView 可以正确显示分组数据,而无需将 CollectionView.ItemTemplate
属性设置为 DataTemplate:
<CollectionView ItemsSource="{Binding Animals}"
IsGrouped="true" />
在此方案中,可以通过替代单个项建模类型和单个项组建模类型中的 ToString
方法来显示有意义的数据。