Hi,
Here is a DataGridView that allows the user to customize its columns during run-time. Its features are:
- Set column visibility
- Set column display text
- Set column display index
- Move columns during run-time (with move indicator)
- Load/Save column options
The column options are accessible for the user via a Column Options Button. This button is shown in the top-left corner of the grid, the area which is usually reserved to select all rows. I don't think this is a feature used by many people so I thought it was an appropriate option. If you don't agree, you can hide the button via the ShowColumnOptionsButton property, and you can activate it instead by calling the ShowColumnOptionsForm manually (in code).

The image on the button can be changed via the ColumnOptionsButtonImage property.
The Column Options form is shown when the button is clicked, and it allows the user to set the display text of columns, as well as hide or show them using a checkbox. All this is done by simply editing the values in the grid directly. To change the display index (order) of the columns, you can drag the rows around, in which case a 'row drag indicator image' will be shown.


In the actual grid (not the 'Column Options form' grid), the user can simply drag around the column headers to re-order them as well. A 'column drag indicator image' will be shown here as well. This image can be set via the ColumnDragIndicatorImage property, and the same image (except rotated 90 degrees) is used for the row dragging in the Column Options form.

UPDATE:
I made an important update that allows you as the developer to do two more things:
- Hide columns from the Column Options form
- Set column options via code
For point 1, often your grid will contain columns such as an ID or DELETED field, which you most probably don't want the user to see. In the old version of this control, these columns would show in the column options form and the user could make them visible. Now you can simply get a GridColumnOptions from the ColumnOptions property (by name, not display text!) and set its ShowInColumnOptionsForm property to false to hide it.
For example, to hide a column named EMPLOYEE_ID from the column options form you use:
vb.net Code:
CustomizeGrid1.ColumnOptions("EMPLOYEE_ID").ShowInColumnOptionsForm = False
For point 2, I realized there was no way to set the options via code. Well, you could set them, but the grid wouldn't reflect the changes. I changed that now, and you can simply get the GridColumnOptions by name again and change whatever property you want. For example, if you want to move the EMPLOYEE_NAME column to index 2 and always hide the EMPLOYEE_ID column, you can use
vb.net Code:
CustomizeGrid1.ColumnOptions("EMPLOYEE_ID").Visible = False
CustomizeGrid1.ColumnOptions("EMPLOYEE_ID").ShowInColumnOptionsForm = False
CustomizeGrid1.ColumnOptions("EMPLOYEE_NAME").DisplayIndex = 2
It is important to note that this is intended to be used with a grid that uses a DataSource. I have tested it with a List(Of T) as its DataSource, but it should work with any IList as far as I know.
It might work with a grid where you set the columns yourself, but in that case you might have to call the InitializeColumnOptions method manually. I'm not sure if it is Public, but you have the source code so if the method is Private you can always change it to Public. This method is usually called automatically when the DataSource changes and will create a list of GridColumnOptions that correspond to the columns in the grid at that time.
When the InitializeColumnOptions method is called, it will create a new GridColumnOptions instance for every column, hence it will use the default values. If you therefor set the DataSource of your grid a second time, this will cause the grid column options to be lost. If you don't want the grid column options to initialize when a new DataSource is set, you can set the DontUpdateColumnOptions property to True. You should use this when your new DataSource is not actually the same object, but it does represent the same data scheme (i.e. it has the same columns).
An example for this would be when you are getting your data from a database. Suppose you are putting the data in a List(Of T) (where T is then some structure or class representing a single entry in the database) which you then bind to the grid. If you need to edit the database (let's say you add a record), then you'll need to refresh the grid by getting the data from the database again, in a New List(Of T). Since this List is no longer the same object as the previous List (even though it will have the same data scheme, columns etc), the DataSourceChanged event of the grid will be raised and the column options will be reset.
To prevent this, set the DontUpdateColumnOptions property to True after you set the DataSource for the first time. This will cause the column options to be initialized the first time a DataSource is assigned, but they will not change a second time after that. Obviously, if you ever do assign a different data scheme (different columns) then you can set the property to False again to let the column options initialize.
I have attached a sample solution which contains the CustomizeGridLibrary (containing the source of the CustomizeGrid control) and a CustomizeGridExample project which is a simple example on how the grid can be used. This example shows you how you could implement a simple 'auto-save' feature to let the grid automatically store its column options when they have changed. It also hides a column from the column options form so you can see how to do that.
The zip file contains two solutions, one for VS2008 and one for VS2010. I have not been able to test if the VS2008 solution works (because I don't have VS2008), but it should work. If not, let me know.
Enjoy!