【问题标题】:Getting index of an item in an ObservableCollection inside the item在项目内的 ObservableCollection 中获取项目的索引
【发布时间】:2015-07-15 17:11:24
【问题描述】:

我希望能够在 DataTemplate 中显示索引值,但我不希望数据被模型或视图模型持久化或支持。换句话说,如果 OC 中项目的顺序发生变化,我不想重新计算索引。该值应在本质上与 OC 中的基础指数相关联。如果索引是从 0 开始的也没关系(事实上,我希望如此)。

其他人使用的一种方法是AlternationIndex AP,但在某些情况下使用has its own pitfalls

最后一个想法:我不禁认为转换器将有助于最终解决方案。

【问题讨论】:

    标签: c# wpf ivalueconverter


    【解决方案1】:

    我会使用转换器来做到这一点。

    诀窍是在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}}"/>
    

    【讨论】:

    • @Rachel 在合理的范围内我不这么认为。它的效率肯定低于绑定一次更新的数据(使用一次集合迭代)。因此,除非您的收藏量很大且经常更改,否则我认为这是安全的。真正的问题是所有额外的枚举(如果我没记错的话,时间复杂度 O(n log n))。当然,OP 要求的解决方案不涉及更有效方法所必需的解决方案。在给定的限制下,这是我能想到的最好的。
    • 我刚刚通过谷歌找到了这个帖子。这个解决方案似乎有效,除了 IEnumerable 没有 indexof 方法。问题是我不能将它转换为实际的集合,而不是接口,因为我不知道集合类型是什么。有人知道 CollectionViewSource.source 的类型是什么吗?
    • @HaloMediaz 在 Bradley 的示例中,它必须是 IEnumerable&lt;object&gt;,但这并不重要。您的转换器会处理这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多