With just a cursory look at the Windows Forms DataGrid control, it is not obvious how to create such simple controls as a Checkbox column, or even how to format, and set the width property, etc. Even after studying the TableStyles collection, it is not straightforward to perform these tasks, and once accomplished, they should be done in such a manner as to make the code reusable.
I have written a class, named CGrid that accomplishes this task. This article will not discuss the code, but will rather demonstrate the use of this class and show the results of using the class in several examples.
As you will note, the class deals with DataTables, but obviously could be enhanced to use DataSets, etc. The purpose of the class is to automatically format data columns, set their width, alignment, and read only properties. Additionally, it can create a Checkbox column and provides a method to call to check or uncheck the column and select the checked row. It accomplishes its polymorphic behavior through the use of several Overloaded methods, which are called based on your requirements.
Example 1, simple grid formatting:
This code gets a DataTable filled by calling a data access class, which is not part of this article. The following code fills the DataTable.
| SQL = "" SQL &= "SELECT DISTINCTROW Equipment.Equip_ID, " SQL &= "Equipment.Equip_Name, " SQL &= "Equipment.Available as Availability, " SQL &= "Equipment.Rented_Date, " SQL &= "Equipment.Available_Date as [Due Back], " SQL &= "Customers.CompanyName, Customers.ContactName, " SQL &= "Customers.PhoneNumber " SQL &= "FROM Customers RIGHT JOIN Equipment ON " SQL &= "Customers.CustomerID = Equipment.Renting_Company_ID " SQL &= "where equipment.available <> 'YES' " oDA.SendQuery(SQL, dt, ConnectString) |
| If dt.Rows.Count > 0 Then Dim Formats() As String = _ {"", "60", "T", "L", _ "", "150", "T", "L", _ "", "60", "T", "L", _ "MM/dd/yyyy hh:mm tt", "130", "T", "L", _ "MM/dd/yyyy hh:mm tt", "130", "T", "L", _ "", "100", "T", "L", _ "", "100", "T", "L", _ "", "100", "T", "L"} oCG.SetTablesStyle(dt, Me.dbgWhoHasIt, Formats) oCG.BindDataTableToGrid(dt, Me.dbgWhoHasIt) End If |

| dtEquip = New DataTable("dt") Me.dbgEquipment.SetDataBinding(dtEquip, "") |
| Dim Formats() As String = {"", "60", "T", "L", _ "", "150", "T", "L", _ "", "50", "T", "L", _ "$#,##0.00", "60", "T", "R", _ "$#,##0.00", "60", "T", "R", _ "$#,##0.00", "60", "T", "R", _ "$#,##0.00", "60", "T", "R", _ "$#,##0.00", "60", "T", "R", _ "", "60", "T", "R", _ "$#,##0.00", "60", "T", "R", _ "0", "60", "T", "R", _ "", "60", "T", "R"} |
| If oDA.SendQuery(SQL, dtEquip, ConnectString) > 0 Then oCG.SetTablesStyle("RentMe", dtEquip, _ Me.dbgEquipment, Formats) oCG.BindDataTableToGrid(dtEquip, Me.dbgEquipment) oCG.DisableAddNew(Me.dbgEquipment, Me) End If |

| Public Overloads Sub SetTablesStyle(ByVal AddCkBox As String, _ ByRef dt As DataTable, _ ByRef dg As DataGrid, _ ByVal ParamArray Formats() As String) ' This method allows a checkbox and optional formatting ' param array. If AddCkBox.Length >0 it will add ' a new first column as a check box ' if paramarray is supplied it is an array of ' four items of "format,width,ReadOnly,alignment,format,width,..." ' where format="$#,##0.00"|"MM/dd/yyyy"|etc ' width = "90", readonly =T|F ' with every column having at least a pair of placeholders, ' including optional checkbox column Dim i As Integer Dim ts As New DataGridTableStyle() Dim myDataCol As New DataGridBoolColumn() ' checkbox column Try ' This call creates the checkbox column and adds to dt If AddCkBox.Length > 0 Then AddCheckBoxColumn(dt, AddCkBox) End If dg.TableStyles.Clear() ts.GridColumnStyles.Clear() ' map the table style to the dt ts.MappingName = "dt" ' set the header and mapping for the ckbox column If AddCkBox.Length > 0 Then With myDataCol .HeaderText = dt.Columns.Item(AddCkBox).ColumnName .MappingName = dt.Columns.Item(AddCkBox).ColumnName .FalseValue = "false" .TrueValue = "true" .AllowNull = False .ReadOnly = True End With ' add the column style for the ckbox col ts.GridColumnStyles.Add(myDataCol) End If ' for the rest of the rows, make text box columns Dim j As Integer For i = 0 To dt.Columns.Count - 1 If Not dt.Columns(i).ColumnName = AddCkBox Then Dim dgtbc As New DataGridTextBoxColumn() dgtbc.HeaderText = _ FixGridColumnCaption(dt.Columns.Item(i).ColumnName) dgtbc.MappingName = dt.Columns.Item(i).ColumnName If UBound(Formats) > 0 Then j = i * 4 dgtbc.Format = Formats(j) dgtbc.Width = Val(Formats(j + 1)) dgtbc.ReadOnly = IIf(Formats(j + 2) = "T", _ True, False) If Formats(j + 3) = "C" Then dgtbc.Alignment = HorizontalAlignment.Center ElseIf Formats(j + 3) = "L" Then dgtbc.Alignment = HorizontalAlignment.Left ElseIf Formats(j + 3) = "R" Then dgtbc.Alignment = HorizontalAlignment.Right End If ts.GridColumnStyles.Add(dgtbc) End If End If Next ' add the table style to the grid dg.TableStyles.Add(ts) Catch ex As System.Exception StructuredErrorHandler(ex) End Try End Sub |
| Public Sub AddCheckBoxColumn(ByRef dt As DataTable, _ ByVal CName As String) ' adds the column for the checkbox to the dt and set to false ' the column will be placed at the end of the datatable, ' but it will appear in the grid in the first column Try dt.Columns.Add(CName) Dim i As Integer For i = 0 To dt.Rows.Count - 1 dt.Rows(i).Item(CName) = "false" Next Catch ex As System.Exception StructuredErrorHandler(ex) End Try End Sub |