使用DataTemplateSelector为CollectionView实现交替行色时出现空引用异常
问题分析与修复方案
核心问题:资源引用大小写不匹配
XAML中定义的DataTemplate键是EvenTemplate和UnevenTemplate(首字母大写),但在AlternateColorDataTemplateSelector的绑定中使用了小写的evenTemplate和unevenTemplate——XAML的资源键区分大小写,这直接导致模板无法被正确加载,EvenTemplate和UnevenTemplate始终为null,最终触发空引用异常。
修复步骤
1. 修正XAML中的资源引用大小写
将选择器的模板绑定改为与资源键完全匹配的大写形式:
<local:AlternateColorDataTemplateSelector x:Key="alternateColorDataTemplateSelector" EvenTemplate="{StaticResource EvenTemplate}" UnevenTemplate="{StaticResource UnevenTemplate}" />
2. 优化选择器代码,避免潜在异常
原OnSelectTemplate方法存在强制转换风险,且IndexOf在大型集合中性能低下,建议改为更安全的实现:
public class AlternateColorDataTemplateSelector : DataTemplateSelector { public DataTemplate EvenTemplate { get; set; } public DataTemplate UnevenTemplate { get; set; } protected override DataTemplate OnSelectTemplate(object item, BindableObject container) { // 安全获取CollectionView和ItemsSource if (container is not CollectionView collectionView || collectionView.ItemsSource is not IList itemsList) return base.OnSelectTemplate(item, container); var index = itemsList.IndexOf(item); return index % 2 == 0 ? EvenTemplate : UnevenTemplate; } }
3. 额外检查:确保模板定义完整
确认EvenTemplate和UnevenTemplate内部的UI元素定义无语法错误,同时验证model:Monkey的命名空间已正确声明:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:model="clr-namespace:YourApp.Models" <!-- 确认此命名空间指向正确的实体类所在位置 --> xmlns:local="clr-namespace:YourApp" x:Class="YourApp.MainPage">
可选:更简洁的交替行实现(MAUI内置方式)
如果仅需实现交替行背景色,MAUI的CollectionView支持AlternationCount属性,无需自定义DataTemplateSelector:
<CollectionView ItemsSource="{Binding Monkeys}" AlternationCount="2"> <CollectionView.ItemTemplate> <DataTemplate> <Grid BackgroundColor="{Binding Source={RelativeSource AncestorType={x:Type CollectionViewItem}}, Path=AlternationIndex, Converter={StaticResource IndexToColorConverter}}"> <!-- 内容布局 --> </Grid> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView>
对应的转换器代码:
public class IndexToColorConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is int index) return index % 2 == 0 ? Colors.LightGray : Colors.White; return Colors.White; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
内容的提问来源于stack exchange,提问作者digidoc1010
相关产品推荐
相关产品推荐

