Introduction
This project is all the bits and pieces that I have implemented in the DataGridView
over the years combined into an extended DataGridView
class. Included among the extra features are sub forms on rows, making an ENTER key press move to the right, CTRL + ' will copy contents from the cell above, alternating row colors without having to set the alternating row cell style, autocomplete textbox column, DateTimePicker column, and a time column.
Background
The features listed in the intro are features that I usually had to program into each individual DataGridView
control that I used. Inevitably I would miss features in some grids and end users would complain. It made my life easier when I encapsulated all these features in a single class that could be utilized from the designer.
Features Detailed
Sub Forms
Sub forms in this project are made to be very similar to the way that MS Access has them but with a few extra features. Things you can do with the sub forms:
- Show different sub forms based on the data bound item of the row
- Specify different types of data to send to the sub form based on the data bound item of the row
- Show multiple sub forms of different types on one row
- Keep the sub forms stationary or mobile when horizontally scrolling the
DataGridViewExtension
- Show a sub form that contains another
DataGridViewExtension
so you can have infinite drill down within the DataGridViewExtension
Enter Moves Right
This feature is selectable in the designer but if enabled, whenever the user presses the Enter key, the focus shifts to the cell on the right (or first cell in the next line) not directly below. This also moves the focus to the right if the user clicks an option from an auto complete list box.
Alternating Row Colors
This is enabled by default with LightGrey as the alternating color. Both the color and enabling/disabling this feature are editable from the designer.
Copy Contents From the Cell Above
As with MS Access, if you press CRTL + ' then the contents of the cell directly above will be pasted into the current cell. This feature is always enabled.
AutoCompleteTextBoxColumn
Adding one of these to your DataGridViewExtension
will allow you to select the type of auto complete you want for the cell, directly from the designer. No more having to implement the EditingControlShowing
event to get your cell to have the auto complete functionality.
DateTimePickerColumn
This shows the date time picker as the editing control for cells in this column. Format
and ShowUpDown
are selectable from the designer.
TimeColumn
This column shows a textbox as the editing control but the value of it is a DateTime
. Entering the time in this cell can be done by entering in 24 hour time, with or without colons, with or without AM/PM, or you can just use 'p' to denote PM. You can enter just hours and minutes, or hour, minutes, and seconds. Time format is editable from the designer.
E.g.: 1600, 400PM, 400 PM, 400p, 400 p, 4:00 PM, 16:00, 4:00p, 4:00pm are all valid ways to enter 4:00 PM.
081530, 81530, 8:15:30a, 8:15:30 AM, 81530a, 081530 AM, 81540am are all valid ways to enter 8:15:30 AM
Using the Code
Sub Forms
This first thing you need to do is create a class that inherits the Extensions.DataGridViewSubForm
class. Only classes that inherit this base class can be set as a sub form of a DataGridViewExtension
. In your class that you create, ensure you have the constructor that accepts an object
and an Extensions.DataGridViewSubformCell
and passes these variables to the base class. The DataGridViewExtension
will always create a new instance of your sub form using this constructor. An example is shown below.
public partial class ShiftSubForm : Extensions.DataGridViewSubForm
{
public ShiftSubForm(object DataBoundItem,
Extensions.DataGridViewSubformCell Cell)
: base(DataBoundItem, Cell)
{
InitializeComponent();
}
private void ShiftSubForm_Load(object sender, EventArgs e)
{
employeeBindingSource.DataSource =
new List<SqlClasses.Data.CharterOperations.Employee>(
new SqlClasses.Data.CharterOperations.Employee[] {
(SqlClasses.Data.CharterOperations.Employee)this.DataBoundItem
});
employeeBindingSource.MoveFirst();
}
}
The DataGridViewSubform
is just an extension of the UserControl
class so you can edit the sub form quite easily in the designer. In the example above, I have a binding source included in the designer. When the form loads, it converts the DataBoundItem
into an Employee list and sets this as the data source for the binding source.
Once you have designed your sub form, you can then add the DataGridViewSubformColumn
to your DataGridViewExtension
. You need to set the column's sub form type manually somewhere in your code, like:
SubFormColumn.Subform = typeof(Controls.ShiftSubForm);
You also need to set the SubformDataMember
property for the column. This can be done in the designer. If you want to pass the OwningRow
's data bound item, just leave this field as 'this
'. You can also choose a member of the data bound item or a member of a member. For example, if I had a Shift and I wanted to pass the Employee's date of birth, then I could have SubformDataMember
as Employee.DOB, but if I wanted to pass the entire employee, then SubformDataMember
would be just Employee.
The other option for a DataGridViewSubformColumn
is the IgnoreSubformDataBindingError
field. If this is set to True
then any errors while trying to retrieve the SubformDataMember
from the OwningRow
's data bound item will be ignored and null
will be sent to the sub form. I recommend that you leave this as False
while debugging. That way it will be easier to see any errors you may have made. But set it to True
for release especially if you are using the member of a member method.
Multiple Sub Forms in One Row
Including multiple DataGridViewSubformColumn
s in a DataGridViewExtension
is perfectly fine. Whichever sub form was last shown will be the one that is placed on top. Here is the result of multiple sub forms in one DataGridViewExtension
:
Sub Form Events
There are two events that belong to the DataGridViewSubformColumn
which are very handy. They are the SubformShowing
and SubformClosing
events. Both events have to be programmed manually somewhere in your code. During both events, you can choose to cancel the showing or closing for the sub form. During the SubformShowing
event, you can set the DataGridViewExtension
to show a different form and specify a different data bound item to use instead of the default SubformDataMember
. An example of how to use the SubformShowing
event is shown below.
void SubFormColumn_SubformShowing(Extensions.DataGridViewSubformCell sender,
Extensions.SubformShowingEventArgs e)
{
if (DoNotShowSubForms)
{
e.Cancel = true;
return;
}
if (((Employee)e.DataBoundItem).Users.Count > 0)
{
e.AlternateForm = typeof(Controls.ShiftSubForm2);
e.DataBoundItem = ((Employee)e.DataBoundItem).Users.First();
}
}
The SubformClosing
event is useful if you need to check the validity of the data contained in the sub form. For example:
void SubFormColumn_SubformClosing(Extensions.DataGridViewSubformCell sender,
Extensions.SubformClosingEventArgs e)
{
if (!((Employee)e.Form.DataBoundItem).IsValid())
{
e.Cancel = true;
MessageBox.Show("The employee details are not correct.")
}
}
Scrolling Sub Forms Horizontally
By default, sub forms remain stationary while you scroll left and right in the DataGridViewExtension
. If you want sub forms to scroll as well, then you need to set the SubformsScrollHorizontally
property of the DataGridViewExtension
to true
, either in code or in the designer.
Enter Moves Right
This feature is enabled by default but to switch if off, you only need to set the EnterMovesRight
property to false
, either in the designer or in the code.
Alternating Row Colors
You can implement this in the designer or in your code. It is enabled by default.
AutoCompleteTexBox Column
Adding one of these columns to the DataGridViewExtension
enables autocomplete on the cells. If you are using a custom source, you can specify the options in the 'Edit Columns' control or programmatically in your code. An example is shown below of how to do it in your code.
Extensions.DataGridViewAutoCompleteTextboxColumn col =
(Extensions.DataGridViewAutoCompleteTextboxColumn)
dataGridViewExtension1.Columns[0];
col.AutoCompleteCollection.AddRange(new string[] {
"Test 1", "Test 2", "Test 3"
});
for (int i = 0; i < 10; i++)
col.AutoCompleteCollection.Add(i.ToString());
DateTimePicker Column
Using this type of column in your DataGridViewExtension
will enable the DateTimePicker
to be the editing control for the cell. The only properties that you have to set in the designer are the format for the control, whether to show the up down instead of the calendar, and the custom format if you choose this format.
TimeColumn
To use this column in your project, the only property that you have to set is the format. You can only use time format strings for this column (i.e.: h, H, m, s, t, hh, HH, mm, ss, tt and :).
History
- 11 May 2011 - Original version posted.
- 17 May 2011 - Fixed positioning bugs and added demo project.
- 20 May 2011 - Fixed bug where subform would be removed if the owning row's
DataBoundItem
implements INotifyPropertyChanged
and this DataBoundItem
was being edited in the sub form.