Skip to content

Instantly share code, notes, and snippets.

@TravisTheTechie
Created January 20, 2010 17:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TravisTheTechie/282024 to your computer and use it in GitHub Desktop.
Save TravisTheTechie/282024 to your computer and use it in GitHub Desktop.
public interface IKeyedObject<T>
{
T Key { get; }
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
public class KeyedCollectionBase<T, K> :
NotifyCollectionChangedBase<T>,
IList<T>
where T : class, IKeyedObject<K>
{
protected readonly IDictionary<K, T> Items = new Dictionary<K, T>();
public virtual T Get(K key)
{
return Items[key];
}
public virtual IEnumerator<T> GetEnumerator()
{
return Items.Values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public virtual void Add(T item)
{
if (Contains(item)) return;
Items.Add(item.Key, item);
var index = IndexOf(item);
OnCollectionChanged(NotifyCollectionChangedAction.Add, item, index);
}
public virtual void Clear()
{
var removedItems = Items.Values.ToList();
Items.Clear();
OnCollectionChanged(NotifyCollectionChangedAction.Reset, removedItems);
}
public virtual bool Contains(K key)
{
return Items.Keys.Contains(key);
}
public virtual bool Contains(T item)
{
return Items.Keys.Contains(item.Key);
}
public virtual void CopyTo(T[] array, int arrayIndex)
{
Items.Values.CopyTo(array, arrayIndex);
}
public virtual bool Remove(T item)
{
var oldItem = Get(item.Key);
var index = IndexOf(oldItem);
var retValue = Items.Remove(item.Key);
OnCollectionChanged(NotifyCollectionChangedAction.Remove, item, index);
return retValue;
}
public virtual int Count
{
get { return Items.Count; }
}
public virtual bool IsReadOnly
{
get { return Items.IsReadOnly; }
}
public virtual int IndexOf(T item)
{
return Items.Values.ToList().IndexOf(item);
}
public virtual void Insert(int index, T item)
{
Add(item);
}
public virtual void RemoveAt(int index)
{
Remove(this[index]);
}
public virtual T this[int index]
{
get { return Items.Values.ToList()[index]; }
set { throw new NotImplementedException(); }
}
public virtual T this[K key] { get { return Get(key); } }
}
using System;
using System.Windows.Threading;
using System.Collections.Generic;
using System.Collections.Specialized;
public class NotifyCollectionChangedBase<T> :
INotifyCollectionChanged
where T : class
{
public event NotifyCollectionChangedEventHandler CollectionChanged;
protected virtual void OnCollectionChanged(NotifyCollectionChangedAction action, T item)
{
OnCollectionChangedThreadSafe(new NotifyCollectionChangedEventArgs(action, item));
}
protected virtual void OnCollectionChanged(NotifyCollectionChangedAction action, T item, int index)
{
OnCollectionChangedThreadSafe(new NotifyCollectionChangedEventArgs(action, item, index));
}
protected virtual void OnCollectionChanged(NotifyCollectionChangedAction action, IList<T> items)
{
OnCollectionChangedThreadSafe(new NotifyCollectionChangedEventArgs(action, items));
}
protected virtual void OnCollectionChangedThreadSafe(NotifyCollectionChangedEventArgs e)
{
NotifyCollectionChangedEventHandler eventHandler = CollectionChanged;
if (eventHandler == null)
return;
Delegate[] delegates = eventHandler.GetInvocationList();
// Walk thru invocation list
foreach (NotifyCollectionChangedEventHandler handler in delegates)
{
DispatcherObject dispatcherObject = handler.Target as DispatcherObject;
// If the subscriber is a DispatcherObject and different thread
if (dispatcherObject != null && dispatcherObject.CheckAccess() == false)
{
// Invoke handler in the target dispatcher's thread
dispatcherObject.Dispatcher.Invoke(DispatcherPriority.DataBind, handler, this, e);
}
else // Execute handler as is
handler(this, e);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment