Search code examples
winformslistviewtagsgenericstyped

Generic WinForms ListView (with regards to Tag)


I'm trying to improve on a Winforms project where datatable rows are stored in the Tag property of ListViewItems. When the datatable is refactored to List<T> (or actually classes containing lists) it would help immensely if I could make the Tag property generic by using a subclass of ListView.

In the best of worlds, I'd want the Tag property to be replaced by a public T Tag{get; set;} that wraps base.Tag and casts it. Second best would be Obsoleting Tag and providing a new property like TypedTag working like above.

I think this would involve subclassing or composite aggregation of at least ListView, ListViewItemCollection, SelectedListViewItemCollection and ListViewItem, and I'm not sure how to do it.

In short:

ListView<Employee> lvwEmployees;

should result in this being possible:

Employee selected = lvwEmployees.SelectedItems[0].TypedTag;

And give a compilation error for this:

DataRow selected = lvwEmployees.SelectedItems[0].TypedTag;

Is it possible? Is it already done? Project is dotnet 2.0 but I think I'll try to have it upgraded if it helps this matter.

EDIT: It turns out that the owner constructor argument is all a certain collection needs to hook up to the inner collection. Hence the following works:

ListView a = new ListView();
a.Items.Add("Hello");
Assert.AreEqual(1, new ListView.ListViewItemCollection(a).Count);

This makes it rather easy to create a generic tagged ListView. I'll post a complete solution later. :)

EDIT2: Here's the solution: http://thecarlr.blogspot.com/2010/11/generic-listview.html

EDIT3: For designer support, just add a non generic subclass and use that. Example: If you intended to use ListView<Employee> in the form, create a ListViewEmployee : ListView<Employee> in another file, and use ListViewEmployee in the form.

The easiest way to add one of theese listviews would be to add a normal listview to the form, and then change it's type in the source files. (And if you don't know where it's declared or instantiated, find out or use the normal listview instead.)


Solution

  • Here's the solution: http://thecarlr.blogspot.com/2010/11/generic-listview.html

    Enjoy :)

    /Carl