.NET 4.0索引与的ObservableCollection [英] .NET 4.0 Indexer with 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屋!