Introduction

I’ve been a member of CodeProject pretty much since its inception in one form or another and have been meaning to post an article for a while, this is a great site and I’m glad that I can finally give something back.

I built the Superlist control whilst developing an RSS reader called FeedGhost. Although there are plenty of commercial grouped list controls available I wanted to have total control over the code and of course its usability. Superlist supports drag drop column customisation, grouping as well as handling thousands of entries smoothly. It’s also highly customisable if you want to change its look and feel. In this article I’ll explain how to use and extend the control in a demo project. If you download the source, you can find demo project under the Tests/SuperListTest directory.

Background

Before deciding to develop my own list control I spent a couple of weeks fighting the standard Listview, trying to get it to work the way I wanted, but I finally gave up when I couldn’t get the selected items in the grouped visual order. We needed this in FeedGhost so that articles that the user multi-selected would be displayed in the same order in the corresponding HTML view.

I decided to write the control from scratch rather than basing it for example on the Grid controls. In previous projects I’ve worked on, I’ve seen the grids bent and warped into doing the bidding of its creator only to be a maintenance millstone around the projects neck later; not quite working the way you want with plenty of patching code to get it *nearly* there. In the end you have a pile of brittle code that people are too scared to touch.

I developed Superlist in two weeks, strangley enough it was about the same time I spent trying to get the Listview working in the first place, admittedly I spent the following two weeks fixing the bugs

Using the Code

The first point to note is I haven’t done any forms designer compatibility work with this control. I tend to use the designer for laying the controls out and then go straight into the code to complete the rest of the work, hence no designer support for Superlist in terms of adding Columns and configuring them etc. To use the control you’ll need of course to add it to a Form or UserControl, then in code you will need to create its columns as in the example below:

Hide Shrink Copy Code

public SuperListTestForm()
{
    InitializeComponent();
    Column surnameColumn = new Column( "surname", "Surname", 120,
        delegate( object item ) { return ((Person)item).Surname; } );
    Column firstnameColumn = new Column( "firstname", "Firstname", 120,
        delegate( object item ) { return ((Person)item).Firstname; } );
    Column phoneColumn = new Column( "phone", "Phone", 100, delegate(
        object item ) { return ((Person)item).Phone; } );
    Column cityColumn = new Column( "city", "City", 60, delegate(
        object item ) { return ((Person)item).City; } );
    Column stateColumn = new Column( "state", "State", 70, delegate(
        object item ) { return ((Person)item).State; } );
    Column dateColumn = new Column( "date", "Date", 110, delegate(
        object item ) { return ((Person)item).Date.ToString(); } );
    dateColumn.GroupItemAccessor = new ColumnItemValueAccessor(
        GroupValueFromItem );
    dateColumn.MoveBehaviour = Column.MoveToGroupBehaviour.Copy;
    dateColumn.GroupSortOrder = SortOrder.Descending;
    surnameColumn.SortOrder = SortOrder.Ascending;
    _superList.Columns.Add( firstnameColumn );
    _superList.Columns.Add( phoneColumn );
    _superList.Columns.Add( stateColumn );
    _superList.Columns.Add( cityColumn );
    _superList.Columns.Add( dateColumn );
    _superList.Columns.GroupedItems.Add( dateColumn );
    _superList.Columns.GroupedItems.Add( stateColumn );
    _superList.SelectedItems.DataChanged +=
    new SelectedItemsCollection.DataChangedHandler(
        SelectedItems_DataChanged );
    int tickStart = Environment.TickCount;
    const int iterationCount = 1; // Change this if you want to increase
                                  // the number of items in the list
    for( int i = 0; i < iterationCount; i++ )
    {
        _superList.Items.AddRange( Person.GetData() );
    }
}
Column Object

The column object is where most of your work lays in terms of getting the control up and running, you create it with the following constructor:

Hide Copy Code

public Column( string name, string caption, int width,
    ColumnItemValueAccessor columnItemValueAccessor )

The name parameter is used to uniquely identify the Column for serialisation etc. The columnItemValueAccessor parameter is a delegate you need to supply that is used to return back the object to render in the associated cell (normally a string):

Hide Copy Code

public delegate object ColumnItemValueAccessor( object rowItem );

Once you’ve defined your columns you can add them to the list via the Columns property.

304 Comments
댓글 남기기