Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / multimedia / GDI+

A fast and simple DataGridView analogue

4.64/5 (4 votes)
18 Jan 2013CPOL2 min read 40K  
Here I placed source files, binaries and brief instructions for FastGrid control.

Introduction

Here is a custom Windows Forms grid control that looks and behaves like standard System.Windows.Forms.DataGridView control. Control is written on .NET 4.0. With the standard grid I used to exploit just a number of its features. I rare used its editing capabilities. Still I often had to implement sorting, columns resizing and some formatting options. So I wrote a simple Grid control and named it FastGrid. It is really somewhat faster than the standard grid: example program includes two samples (FastGrid vs DataGridView). In these samples FastGrid invalidates approx. 40% faster.

The key features of FastGrid control are:

  • it is fast Smile | <img src=  
  • it supports rows’ ordering ‘out of the box’
  • cells’ formatting is a bit more simple for me
  • also, auto size column feature is a bit more predictable

The main point is that FastGrid is given in source code, thus can easily be customized. 

 Image 2

Background

Once upon a time there was a small simple grid control… As time as time goes by, the control grew bigger and smarter. So, here it is.

Using the code

Just place FastGrid on your Form then populate its rows by the code like this:

C#
List<MyObjectClass> objects = GetObjects(…);
fastGrid.DataBind(objects, typeof(MyObjectClass), false, null, 65, string.Empty); 

This way grid generates columns automatically from MyObjectClass type specifications making a column for each public instance property (not marked with Browsable[false] attribute). Column title is either derived from DisplayName attribute or from the property name itself. Then you can just call fastGrid.DataBind(objects) while the column set is already made. You can see how it works on MainForm.cs from TestApp project.

Of course, this way you cannot control most of the things with formatting and user interactions. Instead, you may populate columns programmatically:

C#
grid.columns.Add(new FastColumn("FirstName", "Name")
      {
         ColumnMinWidth = 70,
         SortOrder = FastColumnSort.Ascending
      });

grid.columns.Add(new FastColumn("IsMale", "Gender")
      {
         ColumnWidth = 60,
         /* format cell value: "-" if gender is not specified, "male" for true, "female" for false */
         formatter = c => c == null ? "-" : (bool)c ? "Male" : "Female"
      });

grid.columns.Add(new FastColumn("Occupation", "Occupation")
         {
             ColumnWidth = 70,
             IsHyperlinkStyleColumn = true,
             HyperlinkActiveCursor = Cursors.Hand,
             HyperlinkFontActive = new Font(Font, FontStyle.Bold),
             ColorHyperlinkTextActive = Color.Blue,
             /* highlight unemployed */
             colorColumnFormatter = (object c, out Color? back, out Color? fnt) =>
                    {
                        back = null;
                        fnt = ((Person.PersonOccupation)c) == Person.PersonOccupation.None ? Color.DarkBlue : Color.Black;
                    }
             }); 

First, I added column for a field named "FirstName" and gave it title "Name". I specified that the column should be sorted in ascending order and restricted its minimal width to 70 pixels. NB: I can provide this sorting attribute for more than one column simultaneously. The next column is for a bool? property named IsMale. Here I provided custom formatting logic for this field (formatter). ColumnWidth is set to 60 pixels and will not be changed while the grid is being resized.

Text in the next column ("Occupation") is displayed like hyperlink - it is highlighted when the mouse cursor is over. Also, the text would be printed in DarkBlue when specific condition (Person.Occupation is None) is met. Hyperlink column itself does not provide any logic for handling user click over it. Instead, I use grid's event handler UserHitCell like this:

C#
if (col.PropertyName != "Occupation") return;
var pers = (Person) grid.rows[rowIndex].ValueObject; 

One more note: it is quite simple to obtain all the selected rows or selected objects bound by the following line of code:

C#
var selectedPeople = grid.rows.Where(r => r.Selected).Select(r => (Person) r.ValueObject).ToList(); 

Hope you can make something valuable out of all this code. As a small bonus here comes a Drop Down control FastGridCombo - a drop down box with FastGrid instead of simple list box on expanding.

History 

Published 18.01.2013.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)