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
- 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.
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:
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:
grid.columns.Add(new FastColumn("FirstName", "Name")
{
ColumnMinWidth = 70,
SortOrder = FastColumnSort.Ascending
});
grid.columns.Add(new FastColumn("IsMale", "Gender")
{
ColumnWidth = 60,
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,
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:
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:
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.