- ImplementSelectableVirutalList.zip
- Source
- _ReSharper.SelectableVirtualList
- BuildScriptCache
- .crc
- .version
- ModuleIds.xml
- NamedArguments
- .crc
- .version
- 7
- 1b6a2cee.dat
- PdbInfo
- ProjectModel
- ProjectModel.dat
- Resources
- .crc
- .version
- SymbolCache.bin
- TagPrefixes
- .crc
- .version
- TodoCache
- .crc
- .version
- WebsiteFileReferences
- .crc
- .version
- WordIndex
- .crc
- .version
- nunit.framework.dll
- SelectableVirtualList.5.1.ReSharper.user
- SelectableVirtualList.sln
- SelectableVirtualList
- SelectableVirtualListTest
|
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
namespace SelectableVirtualList
{
public class VirtualList<T> : IList<T>, IList, INotifyCollectionChanged
{
public const int IndexNotFound = -1;
private readonly IObjectGenerator<T> _objectGenerator;
private readonly List<int> _removedItemIndexList = new List<int>();
private T[] _cache;
public VirtualList(IObjectGenerator<T> generator)
{
int maxItems = generator != null ? generator.Count : 0;
_objectGenerator = generator;
_cache = new T[maxItems];
}
internal T[] Cache
{
get { return _cache; }
set { _cache = value; }
}
protected IObjectGenerator<T> ObjectGenerator
{
get { return _objectGenerator; }
}
protected List<int> RemovedItemIndexList
{
get { return _removedItemIndexList; }
}
#region IList Members
public bool IsFixedSize
{
get { return false; }
}
object IList.this[int index]
{
get { return this[index]; }
set { this[index] = (T)value; }
}
public int Add(object value)
{
var item = (T)value;
int index = ObjectGenerator.IndexOf(item);
if (index != IndexNotFound)
{
Insert(index, item);
}
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
return index;
}
public bool Contains(object value)
{
int index = ObjectGenerator.IndexOf((T)value);
if (_removedItemIndexList.Contains(index))
return false;
return index != IndexNotFound;
}
public int IndexOf(object value)
{
return IndexOf((T)value);
}
public void Insert(int index, object value)
{
Insert(index, (T)value);
}
public void Remove(object value)
{
Remove((T)value);
}
public void CopyTo(Array array, int index)
{
}
public virtual bool IsSynchronized
{
get { return false; }
}
public object SyncRoot
{
get { return this; }
}
#endregion
#region Internal helper methods required for caching
protected bool IsItemCached(int index)
{
// If the object is NULL, then it is empty
return (_cache[index] != null);
}
public void CacheItem(int index)
{
// Obtain only a single object
_cache[index] = _objectGenerator.CreateObject(index);
}
#endregion
#region IList<T> Members
public int IndexOf(T item)
{
int index = ObjectGenerator.IndexOf(item);
if (!_removedItemIndexList.Contains(index))
return index;
return IndexNotFound;
}
public void Insert(int index, T item)
{
if (_removedItemIndexList.Contains(index))
_removedItemIndexList.Remove(index);
}
public void RemoveAt(int index)
{
_removedItemIndexList.Add(index);
}
public T this[int index]
{
get { return Get(AdjustIndex(index)); }
set { Insert(index, value); }
}
public void Add(T item)
{
Add(item as object);
}
public void Clear()
{
_removedItemIndexList.Clear();
int numberOfItems = Count;
for (int i = 0; i < numberOfItems; i++)
{
_removedItemIndexList.Add(1);
}
}
public bool Contains(T item)
{
return (IndexOf(item) != -1);
}
public void CopyTo(T[] array, int arrayIndex)
{
_cache.CopyTo(array, arrayIndex);
}
public bool Remove(T item)
{
try
{
int itemPosition = ObjectGenerator.IndexOf(item);
RemoveAt(itemPosition);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
return true;
}
catch (Exception)
{
return false;
}
}
public int Count
{
get { return Cache.Length - _removedItemIndexList.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
IEnumerator IEnumerable.GetEnumerator()
{
return new VirtualEnumerator(this);
}
public IEnumerator<T> GetEnumerator()
{
return new VirtualEnumerator(this);
}
#endregion
#region Internal IEnumerator implementation
protected class VirtualEnumerator : IEnumerator<T>
{
private VirtualList<T> _collection;
private int _cursor;
public VirtualEnumerator(VirtualList<T> collection)
{
_collection = collection;
_cursor = 0;
}
public VirtualList<T> VirtualList
{
get { return _collection; }
set { _collection = value; }
}
#region IEnumerator<T> Members
public T Current
{
get { return _collection[_cursor]; }
}
object IEnumerator.Current
{
get { return Current; }
}
public bool MoveNext()
{
// Check if we are behind
if (_collection.Count == 0 || _cursor == _collection.Count - 1)
return false;
// Increment cursor
++_cursor;
return true;
}
public void Reset()
{
// Reset cursor
_cursor = 0;
}
public void Dispose()
{
// NOP
}
#endregion
}
#endregion
protected virtual T Get(int index)
{
if (!IsItemCached(index))
{
CacheItem(index);
}
return _cache[index];
}
private int AdjustIndex(int index)
{
int adjustedIndex = index;
List<int> orderedRemovedItemList = (from each in _removedItemIndexList
orderby each ascending
select each).ToList();
for (int i = 0; i < orderedRemovedItemList.Count; i++)
{
int removedItemPosition = orderedRemovedItemList[i];
if (removedItemPosition <= adjustedIndex)
{
adjustedIndex++;
}
}
return adjustedIndex;
}
public event NotifyCollectionChangedEventHandler CollectionChanged;
public void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
NotifyCollectionChangedEventHandler handler = CollectionChanged;
if (handler != null)
{
handler(this, e);
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I am a passionated software developer / engineer with strong desire to develop in a simple, fast, beautiful way with the skillset such as simple design, refactoring, TDD. i worked in J2EE for about 5 years, now i work as a .NET devleoper.