【问题标题】:Alternate row color GroupedListview备用行颜色 GroupedListview
【发布时间】:2018-08-01 08:39:05
【问题描述】:

从这个例子:

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

视图模型

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

【问题讨论】:

  • 显示你使用的代码!
  • @TaW 在帖子中添加了一些代码。

标签: c# listview xamarin.forms


【解决方案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;
    }
}

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

结果如下:

【讨论】:

  • 添加了我的视图模型。
  • 啊好吧,这让它变得更复杂了。我想我知道为什么。 IndexOf 可能总是 -1,因为我们现在正在尝试查找 Product 类型,但是因为我们现在使用的是 Grouping,所以我们将 ProductSelectCategoryViewModel 进行比较。那有意义吗?因此,您需要找到一种在列表中找到实际索引的方法,这可能有点挑战
  • 我想为你调查一下,但很遗憾,我现在很忙。应该是明天吧
  • 添加了新回购的答案:)
  • 它不起作用,因为您要逐个添加项目并且仅在单击组后才能添加。在这种情况下,也许您可​​以为模型添加索引并基于此应用样式。或者想办法立即添加项目
猜你喜欢
  • 2012-03-26
  • 2012-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-22
  • 2016-08-18
相关资源
最近更新 更多