An often recurring task is to visualize collections of objects. This article explains how to use an adapter class to fill a
ListView control with completely arbitrary objects.
Using the ListViewAdapter
ListViewAdapter must get some basic information about which properties it should display:
This is enough to get the adapter to display your objects. You could throw an object at it that doesn't have any of the properties
Comment. It would work, but a blank row will just look silly, so please don't.
myCollection object must implement the interface
IEnumerable. Most collections do, so this shouldn't be a problem.
How it works
What makes this piece of magic work is - as most of you probably have figured out - reflection. Reflection is used to discover type information runtime to handle objects that are unknown when you wrote the code.
The first step when the adapter fills a
ListView with objects is to remove existing columns and
ListViewItems. Secondly, it iterates through the bindings and creates the columns. Then it starts filling the
ListView with items:
ListViewItem item=new ListViewItem();
foreach(ColumnBinding b in bindings)
This is the part of the code that builds the actual
ListViewItem. It is pretty straightforward. It loops through the column bindings and tries to get the value, as an
object, of the property that is bound to the column. Then it sends the
object to the parser, which I will explain later, and adds the string returned from the parser to the
There is some additional code which handles images. But if you get the principles of this part of the code, you'll understand how it works when you look at it.
The Parser arose from the need to display information that was interpreted in some way. It is not always desirable to display the result of a
.ToString() call. A Parser object doesn't do anything else than return the result of
.ToString(). But it can be extended to allow more creative interpretations.
An example of a class that extends Parser is the
CustomParser class. The custom parser overrides the
Parse method of its base class and replaces it with a method that uses a delegate to parse the object. So if you don't feel like writing a new class just to parse an object, you can just use the custom parser and provide it with a suitable delegate to do the job.