Click here to Skip to main content
15,878,852 members
Articles / Programming Languages / C#
Article

VivantList: A Control Based List View Control

Rate me:
Please Sign up or sign in to vote.
3.61/5 (11 votes)
14 Nov 20044 min read 88.5K   782   37   12
A fully customizable ListView control, where each row is a control.

Sample chat program using VivantList

Introduction

In this article, I will introduce you to a very customizable control, which can be adjusted to meet many needs.

Background

Our company was searching for a list view control that would support graphics, variable row heights, and controls. After a long search, we found some that came close, but none that could be highly customized… or worked well enough to use. So in a brain storm one day, I came up with the idea of using controls as the rows in a list view. The result was a list view where you could use the VS Forms Designer to design generic rows quickly, or generate them on the fly as complex controls. Through a few generations, the code was customized to compensate for the problems with Windows and how it renders controls through .NET. Of note however, this is not designed to handle lists over 1000. It may do so, but that is beyond what I have used it for.

Using the code

There are five parts in the VivantList Package.

  • VivantList: The core list control
  • VivantRow: A generic row for the VivantList control
  • VivantVerticleScrollbar: A buggy scroll bar created for aesthetic reasons
  • VivantWrapper: A sample wrapper for VivantList
  • ThumbPanel: The thumb panel for the scroll bar

VivantList

VivantList has several public methods. I recommend you look at my demo wrapper for what they all are and how to use them. Play with it, but never add anything other than controls inherited from VivantRow to it.

VivantRow

Every control added directly to VivantList must inherit from VivantRow. VivantRow controls can have any other control placed on them using the Forms Designer. To create a simple row, add a new custom control to your project. Then change the inheritance for System.Windows.Forms.UserControl to VivantLabs.VivantList.VivantRow. Now for something to look at, add some Windows controls to your row using the Forms Designer. My results are as follows:

Sample chat program using VivantList

C#
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

namespace DemoProject
{
    /// <summary>
    /// Summary description for MyRow.
    /// </summary>
    public class MyRow : VivantLabs.VivantList.VivantRow
    {

... Component Designer generated code and the like ...

    }
}

VivantRow has two important properties that make it differ from a common control: RowTop and RowHeight.

  • RowHeight

    This is the height of the row. It must be changed in order to reflect a change in row height in VivantList. Usually, this is the same as the control height of a row. If the row is not rectangular, then this is the height of one row without its overlapping parts.

  • RowTop

    This is the distance in pixels from the top of the control where the 'main' visible region is. In rectangular rows, this is zero.

For a rectangular row:

C#
RowTop = 0;
RowHeight = Control.Height;

Sample chat program using VivantList

In the example picture above, you can see an example of a non-rectangular row. Should you choose to use a non-rectangular row, you will need to research custom shaped controls.

VivantVerticleScrollbar

This is just a side item I created because we didn’t want the Windows look. You can add some images to it and so forth… I suggest using Windows scroll bars.

VivantWrapper

This is the tricky part. VivantWrapper is a control that has VivantList and a scroll bar. If you decide to use VivantList, you may need to rewrite one of these for yourself. I provide this generic one as a guide for those of you interested. This is where your coulomb headers would be, where scrolling should be done, and where any other add-ons go. I recommend you use .NET’s auto control scrolling on this panel. If you have coulomb headers, you may need to wrap VivantList twice, once for scrolling and once for the headers.

Here are some sample functions from my wrapper which shows some of VivantList's methods as well:

C#
public void AddRow(VivantRow Row) 
{
    if ((this.vivantList1.Controls.Count % 2) == 0) 
    {
        Row.UnSelectedBackColor = this.UnSelectedBackColor;
        Row.UnSelectedForeColor = this.UnSelectedForeColor;
    } 
    else 
    {
        Row.UnSelectedBackColor = this.AlternateUnSelectedBackColor;
        Row.UnSelectedForeColor = this.AlternateUnSelectedForeColor;
    }
    Row.SelectedBackColor = this.SelectedBackColor;
    Row.SelectedForeColor = this.SelectedForeColor;

    this.vivantList1.AddRow(Row);
    this.RowtoBottom(this.vivantList1.Controls.Count-1);
    this.verticalScrollBar1.Maximum = this.vivantList1.TotalHeight;
    this.verticalScrollBar1.Value = this.vivantList1.CurrentPostion;
}

public void ClearSelect() 
{
    this.vivantList1.ClearSelect();
}

public void RemoveRow(int index) 
{
    this.vivantList1.RemoveRow(index);
    this.verticalScrollBar1.Maximum = this.vivantList1.TotalHeight;
    this.verticalScrollBar1.Value = this.vivantList1.CurrentPostion;
    SetRowColors();
}

public void InsertRow(int index, VivantRow Row) 
{
    Row.SelectedBackColor = this.SelectedBackColor;
    Row.SelectedForeColor = this.SelectedForeColor;
    Row.UnSelectedBackColor = this.UnSelectedBackColor;
    Row.UnSelectedForeColor = this.UnSelectedForeColor;
    this.vivantList1.InsertRow(index, Row);
    this.verticalScrollBar1.Maximum = this.vivantList1.TotalHeight;
    this.verticalScrollBar1.Value = this.vivantList1.CurrentPostion;
    SetRowColors();
}

public void UnSelectRow(int RowNumber)   
{
    this.vivantList1.UnSelectRow(RowNumber);
}

public void ClearRows() 
{
    this.vivantList1.ClearRows();
    this.verticalScrollBar1.Maximum = this.vivantList1.TotalHeight;
}

ThumbPanel

Just a Thumb Panel drawn on the scrollbar, done by a friend of mine for one implementation of this.

The Demo Project

To make the demo project, seen in the right hand side of the top image, I started with a blank Windows application. Then I created the control called MyRow (seen above). Following that, I dragged a VivantWrapper onto Form1, added a Button and added the following code to the button click event function:

C#
private void button1_Click(object sender, System.EventArgs e)
{
    MyRow tempRow = new MyRow();
    //Must change both the Height and the RowHeight
    tempRow.Height = System.Int32.Parse(this.textBox1.Text);
    tempRow.RowHeight = System.Int32.Parse(this.textBox1.Text);
    this.vivantWrapper1.AddRow(tempRow);
    this.vivantWrapper1.RowtoBottom(this.vivantWrapper1.RowCount - 1);
}

After that, I set a few properties on vivantwrapper1:

C#
this.vivantWrapper1.AlternateRowColors = true;
this.vivantWrapper1.AlternateUnSelectedBackColor = System.Drawing.Color.RoyalBlue;
this.vivantWrapper1.AlternateUnSelectedForeColor = System.Drawing.Color.Black;
this.vivantWrapper1.SelectActiveRow = true;
this.vivantWrapper1.SelectedBackColor = System.Drawing.Color.Blue;
this.vivantWrapper1.SelectedForeColor = System.Drawing.Color.White;
this.vivantWrapper1.UnSelectedBackColor = System.Drawing.Color.CornflowerBlue;
this.vivantWrapper1.UnSelectedForeColor = System.Drawing.Color.Black;

Compile and Run!

One more thing, full vertical tessellation does not work yet. Although I doubt anyone will do this, don’t have controls that slowly change shape but still fit together. While it will be possible to make an Escher out of your list view eventually, right now it's not.

Points of Interest

Some functions seem to be implemented with poor judgment (selection code comes to mind). These are mostly due to the fact that anytime you leave a function block, Windows tries to flush its queue and draw any changes… There is no good way to get around this.

History

  • 11/8/04 - Version 2.1 Posted on CodeProject.
  • 11/9/04 - Updated article and added demo project.
  • 11/15/04 - Updated demo project.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
Particle in a box

Comments and Discussions

 
GeneralProblems when removing first item from list Pin
zokker5-May-05 10:53
susszokker5-May-05 10:53 
GeneralRe: Problems when removing first item from list Pin
ACorbs5-May-05 16:28
ACorbs5-May-05 16:28 
GeneralRe: Problems when removing first item from list Pin
Zoltan Balazs5-May-05 20:02
Zoltan Balazs5-May-05 20:02 
GeneralRe: Problems when removing first item from list Pin
ACorbs6-May-05 11:57
ACorbs6-May-05 11:57 
GeneralRe: Problems when removing first item from list Pin
Zoltan Balazs6-May-05 20:35
Zoltan Balazs6-May-05 20:35 
GeneralVersion 3.0 Alpha Pin
ACorbs2-Mar-05 12:56
ACorbs2-Mar-05 12:56 
GeneralA Little Information about Version 3.0 Pin
ACorbs29-Dec-04 2:56
ACorbs29-Dec-04 2:56 
GeneralSuper! Pin
A.Wegierski25-Nov-04 20:14
A.Wegierski25-Nov-04 20:14 
GeneralVersion 2.2 Soon Pin
ACorbs19-Nov-04 11:17
ACorbs19-Nov-04 11:17 
GeneralUPDATE: Skipping 2.2 Pin
ACorbs22-Nov-04 19:39
ACorbs22-Nov-04 19:39 
GeneralZaebatelskiy kod Pin
0 rc9-Nov-04 20:57
0 rc9-Nov-04 20:57 
Nu, I nahuy sprahivaets'y eto uebishe vilogili. Bizdec, Indusy zaebaly svoim kodom ohuitelnim delitsy. Pihu na translite - na Anglickom tak ne peredat'.

Good code! Thank's Wink | ;)
GeneralRe: Zaebatelskiy kod Pin
ACorbs19-Nov-04 11:13
ACorbs19-Nov-04 11:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.