onsdag 17 november 2010

Generic ListView

I needed a generic ListView with a typed Tag property for the ListViewItems.
It turned out it wasn't so difficult. Here's the source:



    /// <summary>
/// Typed ListViewItem v1.1 by Carl Ribbegårdh
/// </summary>
/// <typeparam name="T">The type of the Tag object</typeparam>
public class ListViewItem<T> : ListViewItem where T : class
{
public ListViewItem() : base()
{}

public ListViewItem(string text) : base(text)
{}

public ListViewItem(string text, int imageIndex) : base(text, imageIndex)
{}

public ListViewItem(string text, string imageKey) : base(text, imageKey)
{}

public new T Tag
{
get { return base.Tag as T; }
set { base.Tag = value; }
}
}

/// <summary>
/// Typed ListView v1.1 by Carl Ribbegårdh
/// </summary>
/// <typeparam name="T">The type of the Tag object</typeparam>
public class ListView<T> : ListView where T : class
{
public ListView() : base()
{}

public new class ListViewItemCollection : ListView.ListViewItemCollection
{
private ListView m_owner;

public ListViewItemCollection(ListView<T> owner) : base(owner)
{
m_owner = owner;
}


public new ListViewItem<T> this[int index]
{
get
{
return (ListViewItem<T>)base[index];
}
set
{
base[index] = value;
}
}

public new ListViewItem<T> this[string key]
{
get
{
return (ListViewItem<T>)base[key];
}
}

public ListViewItem<T> Add(ListViewItem<T> value)
{
return (ListViewItem<T>)base.Add(value);
}

[Obsolete("Please use the generic Add instead.", true)]
public new ListViewItem Add(ListViewItem value)
{
throw new NotSupportedException("Please use the generic Add instead.");
}

public new ListViewItem<T> Add(string text)
{
return (ListViewItem<T>)base.Add(new ListViewItem<T>(text));
}

public new ListViewItem<T>[] Find(string key, bool searchAllSubItems)
{
List<ListViewItem<T>> result = new List<ListViewItem<T>>();
foreach (var item in base.Find(key, searchAllSubItems))
{
result.Add((ListViewItem<T>)item);
}
return result.ToArray();
}

public new IEnumerator<ListViewItem<T>> GetEnumerator()
{
IEnumerator baseEnumerator = base.GetEnumerator();
while (baseEnumerator.MoveNext())
{
yield return (ListViewItem<T>)baseEnumerator.Current;
}
}

[Obsolete("Please use the generic Insert instead.", true)]
public new ListViewItem<T> Insert(int index, ListViewItem item)
{
throw new NotSupportedException("Please use the generic Insert instead.");
}

public ListViewItem<T> Insert(int index, ListViewItem<T> item)
{
return (ListViewItem<T>)base.Insert(index, item);
}
public new ListViewItem<T> Insert(int index, string text)
{
return (ListViewItem<T>)base.Insert(index, new ListViewItem<T>(text));
}
public new ListViewItem<T> Insert(int index, string text, int imageIndex)
{
return (ListViewItem<T>)base.Insert(index, new ListViewItem<T>(text, imageIndex));
}
public new ListViewItem<T> Insert(int index, string text, string imageKey)
{
return (ListViewItem<T>)base.Insert(index, new ListViewItem<T>(text, imageKey));
}
public new ListViewItem<T> Insert(int index, string key, string text, int imageIndex)
{
ListViewItem<T> item = new ListViewItem<T>(text, imageIndex);
item.Name = key;
return (ListViewItem<T>)base.Insert(index, item);
}
public new ListViewItem<T> Insert(int index, string key, string text, string imageKey)
{
ListViewItem<T> item = new ListViewItem<T>(text, imageKey);
item.Name = key;
return (ListViewItem<T>)base.Insert(index, item);
}
}

public new class SelectedListViewItemCollection : ListView.SelectedListViewItemCollection
{
public SelectedListViewItemCollection(ListView<T> owner) : base(owner)
{}

public new ListViewItem<T> this[int index]
{
get { return base[index] as ListViewItem<T>; }
}

public virtual new ListViewItem<T> this[string key]
{
get { return base[key] as ListViewItem<T>; }
}
}

public new class CheckedListViewItemCollection : ListView.CheckedListViewItemCollection
{
public CheckedListViewItemCollection(ListView<T> owner) : base(owner)
{}

public new ListViewItem<T> this[int index]
{
get { return base[index] as ListViewItem<T>; }
}

public virtual new ListViewItem<T> this[string key]
{
get { return base[key] as ListViewItem<T>; }
}
}

public new ListView<T>.ListViewItemCollection Items
{
get
{
return new ListView<T>.ListViewItemCollection(this);
}
}

public new ListView<T>.SelectedListViewItemCollection SelectedItems
{
get
{
return new ListView<T>.SelectedListViewItemCollection(this);
}
}

public new ListView<T>.CheckedListViewItemCollection CheckedItems
{
get
{
return new ListView<T>.CheckedListViewItemCollection(this);
}
}
}




Let's say it's in BSD license. :)

It could use some more constructors, and a couple more collections implemented. I'll update the source if that happens.

There's no unit tests for it, so I'll be happy for any bug fixes or bug reports.

The code I just used it for works. ;)

/Carl


Here's where it started earlier today:
http://stackoverflow.com/questions/4207279/generic-winforms-listview-with-regards-to-tag

Inga kommentarer:

Skicka en kommentar