User Interface Refinements
|Figure 1: The DataGrid displays a custom set of columns but column width and background color are not yet properly set.|
Even with just the number of columns you want, the DataGrid is far from being perfect. You need to assign proper widths to the various columns so that all the data is displayed in its entirety. Columns do have a width
property but unless you take ad hoc countermeasures, that is not enough to ensure that the full client area is covered. Figure 1
shows what I mean.
shows two of the things I really hate in the Windows Forms DataGrid. Although effective, the default user interface of the grid looks like a well done half work. First, the average programmer doesn't want different colors between the control's background (dark gray) and the grid's background (white). Second, the width of all columns should be set in such a way that the data spans over the whole horizontal axis. More important, the width of all columns should be automatically adjusted as the grid is resized. Figure 2
shows a much more elegant and professional-looking grid. (See Sidebar: The ControlPaint Class
|Figure 2: Columns span to cover all the available space and the background is set to make the UI more uniform.|
property defines the color of the client area of the grid windowthe dark gray space in Figure 1
. For a better visual effect you might want to synchronize it with the column's background colors.
Dim col3 As DataGridTextBoxColumn
col3 = New DataGridTextBoxColumn()
col3.TextBox.Enabled = False
col3.HeaderText = "First Name"
col3.MappingName = "firstname"
col3.Width = CalculateExactWidth(grid, _
In the code snippet I give all columns but the last a fixed width that users can modify interactively using their mouse. The last column is given a dynamically computed width. To ensure that it is always set to the exact number of pixels left, I sum up the width of all preceding columns with the value of the RowHeaderWidth
DataGrid property. The final result is subtracted from the DataGrid's overall width. The RowHeaderWidth
property determines the width of the leftmost gray selector column of the grid. A bit trickier is ensuring that the columns always span over the available horizontal space even when the form is resized. The SizeChanged
event is key to achieve this. The following code snippet shows the source of the size handler.
Sub grid_SizeChanged(ByVal sender As Object, _
ByVal e As EventArgs) _
Dim grid As DataGrid
grid = CType(sender, DataGrid)
If grid.TableStyles.Count <= 0 Then
Dim cst As GridColumnStylesCollection
cst = grid.TableStyles(0).GridColumnStyles
Dim lastCol As Integer
lastCol = cst.Count-1
Dim cw As Integer
cw = CalculateExactWidth(grid, cst)
cst(lastCol).Width = cw
If you look at the programming interface of the DataGrid control, you notice that only two types of columns are definedDataGridTextBoxColumn
. The reason for this will be clear in a moment. For now it is sufficient to say that, in practice, either you use a textbox style rendering or a checkbox if the column is marked as Boolean. Should you need to display other types of data in the cells (such as pictures, drop-down lists, embedded forms, mixed text, or images) you must resort to writing your own column type. (More on this shortly.)