In a comment to my previous post on collections, Eddie Garmon posted a link to his Visual Studio Templates (with Installer). It's a good set of templates, and even better, you can modify them to suit your needs, if you know where to do it. I quickly modified his template for a typed collection, to add design-time support by implementing IComponent and IDisposable (thanks Mark!).
Here's the modified template (Eddie's template collection lives in “C:\Program Files\Microsoft Visual Studio .NET 2003\VC#\VC#Wizards\SPAddCollectionWiz\Templates\1033” on my machine.)
using System;
using System.Collections;
using System.ComponentModel;
namespace [!output SAFE_NAMESPACE_NAME] {
[ToolboxItem(true)]
[DesignTimeVisible (true)]
[Serializable]
public class [!output COLLECTION_CLASS_NAME] : CollectionBase, IComponent, IDisposable {
public [!output COLLECTION_CLASS_NAME]() {}
public [!output INNER_TYPE_NAME] this[int index] {
get { return ([!output INNER_TYPE_NAME])List[index]; }
set { List[index] = value; }
}
public int Add([!output INNER_TYPE_NAME] value) {
return List.Add(value);
}
public void AddRange([!output INNER_TYPE_NAME][] value) {
for (int i = 0; i < value.Length; i++) {
Add(value[i]);
}
}
public void AddRange([!output COLLECTION_CLASS_NAME] value) {
for (int i = 0; i < value.Count; i++) {
Add(value[i]);
}
}
public bool Contains([!output INNER_TYPE_NAME] value) {
return List.Contains(value);
}
public void CopyTo([!output INNER_TYPE_NAME][] array, int index) {
List.CopyTo(array, index);
}
public int IndexOf([!output INNER_TYPE_NAME] value) {
return List.IndexOf(value);
}
public void Insert(int index, [!output INNER_TYPE_NAME] value) {
List.Insert(index, value);
}
public void Remove([!output INNER_TYPE_NAME] value) {
List.Remove(value);
}
public [!output COLLECTION_CLASS_NAME] SubCollection(int start, int count) {
if ((start > List.Count) || (start + count > List.Count)) {
throw new ArgumentException("SubCollection request is invalid.");
}
[!output COLLECTION_CLASS_NAME] collection = new [!output COLLECTION_CLASS_NAME]();
for (int i = start; i < start + count; i++) {
collection.Add(([!output INNER_TYPE_NAME])List[i]);
}
return collection;
}
#region IComponent Members
// Added to implement Site property correctly.
private ISite _site = null;
///
/// Get/Set the site where this data is
/// located.
///
public ISite Site
{
get { return _site; }
set { _site = value; }
}
#endregion
#region IDisposable Members
///
/// Notify those that care when we dispose.
///
public event System.EventHandler Disposed;
///
/// Clean up. Nothing here though.
///
public void Dispose()
{
// Nothing to clean.
if (Disposed != null)
Disposed (this, EventArgs.Empty);
}
#endregion
}
}