.NET 4.0索引与的ObservableCollection [英] .NET 4.0 Indexer with ObservableCollection

查看:182
本文介绍了.NET 4.0索引与的ObservableCollection的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是有一个索引一个ObservableCollection的.NET C#语法?我想一个ObservableColletion并参考项目按序号位置或字符串名称。我知道你用这个来表示一个索引,但我不知道如何把在一个ObservableCollection。谢谢

What is the .NET C# syntax for an ObservableCollection with an indexer? I would like an ObservableColletion and refer to the items by ordinal position or a string name. I know you the use this to denote an indexer but I don't know how to put that in an ObservableCollection. Thanks

谢谢你的4答案。我知道如何创建和的ObservableCollection,我知道如何创建一个索引。我不知道如何将它们结合起来。我要求的样品code与序数和字符串索引一个ObservableCollection。 再次感谢

Thanks for the 4 answers. I know how create and ObservableCollection and I know how to create an indexer. I don't know how to combine them. I am asking for sample code for an ObservableCollection with an ordinal and string index. Thank again

推荐答案

的ObservableCollection从集合继承,因此它已经拥有基于位置的索引。

ObservableCollection inherits from Collection, so it already has position-based indexing.

有关基于字符串的索引,你可以看看ObservableDictionary人民实现。

For string-based indexing, you can look into peoples implementations of ObservableDictionary.

就个人而言,有更好的表现,我创建了一个HashedObservableCollection距离的ObservableCollection派生包含密钥的字典来索引来加快查找时间。通过重写InsertItem,RemoveItem和ClearItems,你保持同步字典。

Personally, for better performance, I've created a HashedObservableCollection deriving from ObservableCollection which contains a Dictionary of keys to indexes to speed lookup time. By overriding InsertItem, RemoveItem, and ClearItems, you keep the dictionary in sync.

在我的例子中,键可以是任何类型的,但我们假设密钥永远不会改变 - 如果项被替换,它被替换的对象使用相同的密钥。如果你想简化这一点,你可以用替换字符串TKEY的。

In my example, the keys can be of any type but we assume the key never changes - if an item is replaced, it is replaced with an object with the same key. If you want to simplify this, you can replace TKey with String.

code:

using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace foson.Utils
{
    /// <summary>
    /// Represents BindableCollection indexed by a dictionary to improve lookup/replace performance.
    /// </summary>
    /// <remarks>
    /// Assumes that the key will not change and is unique for each element in the collection.
    /// Collection is not thread-safe, so calls should be made single-threaded.
    /// </remarks>
    /// <typeparam name="TValue">The type of elements contained in the BindableCollection</typeparam>
    /// <typeparam name="TKey">The type of the indexing key</typeparam>
    public class HashedBindableCollection<TValue, TKey> : ObservableCollection<TValue>
    {

        protected internal Dictionary<TKey, int> indecies = new Dictionary<TKey, int>();
        protected internal Func<TValue, TKey> _keySelector;

        /// <summary>
        /// Create new HashedBindableCollection
        /// </summary>
        /// <param name="keySelector">Selector function to create key from value</param>
        public HashedBindableCollection(Func<TValue, TKey> keySelector)
            : base()
        {
            if (keySelector == null) throw new ArgumentException("keySelector");
            _keySelector = keySelector;
        }

        #region Protected Methods
        protected override void InsertItem(int index, TValue item)
        {
            var key = _keySelector(item);
            if (indecies.ContainsKey(key))
                throw new DuplicateKeyException(key.ToString());

            if (index != this.Count)
            {
                foreach (var k in indecies.Keys.Where(k => indecies[k] >= index).ToList())
                {
                    indecies[k]++;
                }
            }

            base.InsertItem(index, item);
            indecies[key] = index;

        }

        protected override void ClearItems()
        {
            base.ClearItems();
            indecies.Clear();
        }


        protected override void RemoveItem(int index)
        {
            var item = this[index];
            var key = _keySelector(item);

            base.RemoveItem(index);

            indecies.Remove(key);

            foreach (var k in indecies.Keys.Where(k => indecies[k] > index).ToList())
            {
                indecies[k]--;
            }
        }
        #endregion

        public virtual bool ContainsKey(TKey key)
        {
            return indecies.ContainsKey(key);
        }

        /// <summary>
        /// Gets or sets the element with the specified key.  If setting a new value, new value must have same key.
        /// </summary>
        /// <param name="key">Key of element to replace</param>
        /// <returns></returns>
        public virtual TValue this[TKey key]
        {

            get { return this[indecies[key]]; }
            set
            {
                //confirm key matches
                if (!_keySelector(value).Equals(key))
                    throw new InvalidOperationException("Key of new value does not match");

                if (!indecies.ContainsKey(key))
                {
                    this.Add(value);
                }
                else
                {
                    this[indecies[key]] = value;
                }
            }
        }

        /// <summary>
        /// Replaces element at given key with new value.  New value must have same key.
        /// </summary>
        /// <param name="key">Key of element to replace</param>
        /// <param name="value">New value</param>
        /// 
        /// <exception cref="InvalidOperationException"></exception>
        /// <returns>False if key not found</returns>
        public virtual bool Replace(TKey key, TValue value)
        {
            if (!indecies.ContainsKey(key)) return false;
            //confirm key matches
            if (!_keySelector(value).Equals(key))
                throw new InvalidOperationException("Key of new value does not match");

            this[indecies[key]] = value;
            return true;

        }

        public virtual bool Remove(TKey key)
        {
            if (!indecies.ContainsKey(key)) return false;

            this.RemoveAt(indecies[key]);
            return true;

        }

    }
    public class DuplicateKeyException : Exception
    {

        public string Key { get; private set; }
        public DuplicateKeyException(string key)
            : base("Attempted to insert duplicate key " + key + " in collection")
        {
            Key = key;
        }
    }
}

这篇关于.NET 4.0索引与的ObservableCollection的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆