从此示例:
https://blog.verslu.is/stackoverflow-answers/alternate-row-color-listview/
如何使用分组列表视图实现它?我想在列表视图的每个组中都有备用行颜色,我已经尝试用分组的列表视图实现它,但是总是给我“ System.InvalidCastException:指定的转换无效”。在DataTemplateSelector中。
列表视图代码:
<DataTemplate x:Key="evenTemplate">
<ViewCell>
<customRenders:GridConf Margin="0,0,0,0" HorizontalOptions="FillAndExpand" ColumnSpacing="0" RowSpacing="0" ConfigurationItem ="{Binding .}">
<customRenders:GridConf.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="*"/>
</customRenders:GridConf.ColumnDefinitions>
<customRenders:GridConf.RowDefinitions>
<RowDefinition Height="*"/>
</customRenders:GridConf.RowDefinitions>
<BoxView VerticalOptions="CenterAndExpand" HeightRequest="50" Grid.ColumnSpan="1" Margin="-30,0,0,0" Grid.Column="1" HorizontalOptions="FillAndExpand" BackgroundColor="LightGray"/>
<Label VerticalOptions="CenterAndExpand" Margin="10,0,0,0" Grid.Column="1" VerticalTextAlignment="Center" HorizontalOptions="StartAndExpand" Text="tetetetetetet"></Label>
<Image Grid.Column="1" Source="HidePass.png" HeightRequest="30" VerticalOptions="CenterAndExpand" HorizontalOptions="End">
<Image.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1" ></TapGestureRecognizer>
</Image.GestureRecognizers>
</Image>
<customRenders:CachedImageItem Grid.Column="0" ConfigurationItem ="{Binding .}" HorizontalOptions="Start" HeightRequest="80" VerticalOptions="Center" x:Name="Image2" Source="{Binding Img}"/>
<customRenders:GridConf.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1" ></TapGestureRecognizer>
</customRenders:GridConf.GestureRecognizers>
</customRenders:GridConf>
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="unevenTemplate">
<ViewCell>
<customRenders:GridConf Margin="20,0,0,0" HorizontalOptions="FillAndExpand" ColumnSpacing="0" RowSpacing="0" ConfigurationItem ="{Binding .}">
<customRenders:GridConf.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="*"/>
</customRenders:GridConf.ColumnDefinitions>
<customRenders:GridConf.RowDefinitions>
<RowDefinition Height="*"/>
</customRenders:GridConf.RowDefinitions>
<BoxView VerticalOptions="CenterAndExpand" HeightRequest="50" Grid.ColumnSpan="1" Margin="-30,0,0,0" Grid.Column="1" HorizontalOptions="FillAndExpand" BackgroundColor="LightGray"/>
<Label VerticalOptions="CenterAndExpand" Margin="10,0,0,0" Grid.Column="1" VerticalTextAlignment="Center" HorizontalOptions="StartAndExpand" Text="teteteteteette"></Label>
<Image Grid.Column="1" Source="HidePass.png" HeightRequest="30" VerticalOptions="CenterAndExpand" HorizontalOptions="End">
<Image.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1" ></TapGestureRecognizer>
</Image.GestureRecognizers>
</Image>
<customRenders:CachedImageItem Grid.Column="0" ConfigurationItem ="{Binding .}" HorizontalOptions="Start" HeightRequest="80" VerticalOptions="Center" x:Name="Image2" Source="{Binding Img}"/>
<customRenders:GridConf.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1" ></TapGestureRecognizer>
</customRenders:GridConf.GestureRecognizers>
</customRenders:GridConf>
</ViewCell>
</DataTemplate>
<customRenders1:AlternateColorDataTemplateSelector2 x:Key="alternateColorDataTemplateSelector"
EvenTemplate="{StaticResource evenTemplate}"
UnevenTemplate="{StaticResource unevenTemplate}" />
</ResourceDictionary>
</ContentPage.Resources>
<ListView x:Name="lst" IsGroupingEnabled="True" ItemTemplate="{StaticResource alternateColorDataTemplateSelector}" ItemsSource="{Binding Item}" Margin="5,5,0,0" HasUnevenRows="True" SeparatorVisibility="None">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<customRenders:NativeCell>
<customRenders:NativeCell.View>
<ContentView Padding="10,0,0,0">
<StackLayout>
<Label Text="{Binding Key.Category}" VerticalOptions="Center"/>
</StackLayout>
<ContentView.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={x:Reference ProtocolosPage}, Path=BindingContext.HeaderSelectedCommand}" CommandParameter="{Binding .}"/>
</ContentView.GestureRecognizers>
</ContentView>
</customRenders:NativeCell.View>
</customRenders:NativeCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
</ListView>
AlternateColorDataTemplateSelector:
public DataTemplate EvenTemplate { get; set; }
public DataTemplate UnevenTemplate { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
// TODO: Maybe some more error handling here
return ((List<Product>)((ListView)container).ItemsSource).IndexOf(item as Product) % 2 == 0 ? EvenTemplate : UnevenTemplate;
}
ViewModel
public class ProductsViewModel: BindableBase
{
public class SelectCategoryViewModel
{
public string Category { get; set; }
public bool Selected { get; set; }
}
private ObservableCollection<Grouping<string, Product>> _ProductsGrouped;
public ObservableCollection<Product> Productitems { get; set; }
public ObservableCollection<Grouping<string, Models.Product>> ProductsGrouped
{
get
{
return _ProductsGrouped;
}
set
{
_ProductsGrouped = value;
OnPropertyChanged();
}
}
public ObservableCollection<Grouping<SelectCategoryViewModel, Product>> Item { get; set; }
public DelegateCommand<Grouping<SelectCategoryViewModel, Product>> HeaderSelectedCommand
{
get
{
return new DelegateCommand<Grouping<SelectCategoryViewModel, Product>>(g =>
{
if (g == null) return;
g.Key.Selected = !g.Key.Selected;
if (g.Key.Selected)
{
Productitems.Where(i => (i.Category.Equals(g.Key.Category)))
.ForEach(g.Add);
}
else
{
g.Clear();
}
});
}
}
public ProductsViewModel()
{
Productitems = new ObservableCollection<Product>
{
new Product
{
Img = "dss.png",
Url = "Teste",
Category = "service",
Title = "sdsadsadsdsdsa"
},
new Product
{
Img = "dss.png",
Url = "Teste3",
Category = "service",
Title = "sdsadsadsdsdsatest2"
},
new Product
{
Img = "dss.png",
Url = "Teste2",
Category = "Farmacy",
Title = "sdsadsadsdsdsaes"
},
new Product
{
Img = "dss.png",
Url = "Teste4",
Category = "Farmacy",
Title = "sdsadsadsdsdsaF"
},
new Product
{
Img = "dss.png",
Url = "Teste7",
Category = "Farmacy",
Title = "sdsadsadsdsdsaFarmarcia2"
},
new Product
{
Img = "dss.png",
Url = "Teste9",
Category = "Farmacy",
Title = "sdsadsadsdsdsae"
}
};
Item = new ObservableCollection<Grouping<SelectCategoryViewModel, Product>>();
var selectCategories =
Productitems.Select(x => new SelectCategoryViewModel { Category = x.Category, Selected = false })
.GroupBy(sc => new { sc.Category })
.Select(g => g.First())
.ToList();
selectCategories.ForEach(sc => Item.Add(new Grouping<SelectCategoryViewModel, Product>(sc, new List<Product>())));
}
}
答案 0 :(得分:1)
这不起作用,因为AlternateColorDataTemplateSelector
中的代码将ItemSource
强制转换为List
。使用分组时,它不能是简单的列表。
另一方面,当您对一个组执行IndexOf
时,您将收到该组中的索引,该索引不需要与完整列表中的索引相对应。
在此处找到示例存储库:https://github.com/jfversluis/GroupedListViewAlternateRowColor。
在改编的DataTemplateSelector
中,我将整个列表弄平,然后从那里获取索引。这是代码:
public class AlternateColorDataTemplateSelector : DataTemplateSelector
{
public DataTemplate EvenTemplate { get; set; }
public DataTemplate UnevenTemplate { get; set; }
private List<string> flatList;
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
if (flatList == null)
{
var groupedList = (ObservableCollection<Grouping<string, string>>)((ListView)container).ItemsSource;
flatList = groupedList.SelectMany(group => group).ToList();
}
return flatList.IndexOf(item as string) % 2 == 0 ? EvenTemplate : UnevenTemplate;
}
}
作为一种优化,我只创建了平面列表一次。每当列表使用新项目更新时,这可能会出错。我没有测试。
结果如下: