代码之家  ›  专栏  ›  技术社区  ›  Phill

替换行颜色GroupedListview

  •  0
  • Phill  · 技术社区  · 8 年前

    从这个例子来看:

    https://blog.verslu.is/stackoverflow-answers/alternate-row-color-listview/

    如何使用分组列表视图实现它?我想在listview的每个组中都有备用的行颜色,我已经尝试用分组的listview实现它,但是在DataTemplateSelector中总是给我“System.InvalidCasteException:指定的强制转换无效”。

    列表视图代码:

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

    视图模型

    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>())));
        }
    }
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Gerald Versluis    8 年前

    这不起作用,因为 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;
        }
    }
    

    作为优化,我只创建一次平面列表。每当用新项目更新列表时,这可能会出错。我没有测试。

    结果如下:

    Grouped ListView alternate row color