在项内获取ObservableCollection中项的索引

5
我希望能够在DataTemplate内显示索引值,但是我不想将数据持久化或由模型或ViewModel支持。换句话说,如果OC中的项目顺序发生变化,我不想重新计算索引。该值应与OC中的基础索引固有地绑定在一起。如果索引是从0开始的(实际上,我会这样期望),那么也可以。其他人使用的一种方法是AlternationIndex AP,但这对某些情况有其自身的缺陷。最后一个想法:我不能不认为转换器在最终解决方案中会很有用。
1个回答

9

我会使用转换器来完成这个任务。

关键是提供源集合,可以在ConverterParameter或依赖属性上设置。此时,转换就像使用IndexOf一样简单。

这是一个执行此操作的示例转换器:

public class ItemToIndexConverter : IValueConverter
{
    public object Convert(...)
    {
        CollectionViewSource itemSource = parameter as CollectionViewSource;
        IEnumerable<object> items = itemSource.Source as IEnumerable<object>;

        return items.IndexOf(value as object);
    }

    public object ConvertBack(...)
    {
        return Binding.DoNothing;
    }
}

您可以通过使实现强类型化、返回格式化的数字字符串等方式来对其进行实现。但基本模式将与上面相同。

此实现使用参数方法,因为在我看来,制作DP更加混乱。由于无法绑定ConverterParameter,因此我将其设置为静态资源,该静态资源已绑定到集合:

<CollectionViewSource x:Key="collectionSource" Source="{Binding Path=MyCollection}" />

...

<TextBlock Text="{Binding Converter={StaticResource ResourceKey=ItemToIndexConverter}, 
               ConverterParameter={StaticResource ResourceKey=collectionSource}}"/>

2
@Rachel 在合理的范围内,我认为不会有问题。它肯定比绑定只更新一次数据(使用集合的一个迭代)要低效。因此,除非您的集合非常庞大且经常更改,否则我认为这是安全的。真正的问题在于所有额外的枚举(如果我没有错的话,时间复杂度为O(n log n))。当然,OP要求解决方案不涉及更高效方法所必需的内容。在给定的约束条件下,这是我能想到的最好的解决方案。 - BradleyDotNET
1
我刚通过谷歌找到了这个线程。这个解决方案似乎有效,但是IEnumerable没有indexof方法。问题在于我无法将其转换为实际的集合,而不是接口,因为我不知道集合类型是什么。有人知道CollectionViewSource.source的类型是什么吗? - HaloMediaz
1
@HaloMediaz 在 Bradley 的例子中,它只需要是一个 IEnumerable<object>,但实际上并不重要。你的转换器会处理它。 - Lynn Crumbling

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接