![]() |
Languages »
C / C++ Language »
General
Intermediate
Gain Access To DataGridView Canned ControlsBy mark.stratmanHow to gain access to the DataGridViewComboBoxEditingControl’s properties, methods, and events. |
VB, Windows, .NET 2.0, ADO.NET, WinForms, VS2005, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||

Why reinvent the wheel when you can just get new hub caps? In this article, I will show how to gain access to the DataGridViewComboBoxEditing control�s properties, methods, and events. Other examples I�ve seen show how to implement custom controls, but I didn�t want to create my own DropDownList control. What I needed was to change the DisplayStyle to DropDownButton, alternate the BackColor of the list, and set the ForeColor to red if the list item begins with EXPIRED.
The first item is a no brainer, the DisplayStyle is one of the few properties exposed by the DataGridViewComboBoxColumn. The other two, however, have no properties, methods, or events exposed that can allow these changes. With the ComboBox control, you could use the DrawItem event, or override the OnDrawItem method to accomplish this. But the DataGridViewComboBoxColumn does not expose the ComboBox, in fact it is obscured by three classes. The DataGridViewComboBoxColumn contains a DataGridViewComboBoxCell object which contains a DataGridViewComboBoxEditingControl object which inherits from the ComboBox class. Urggggg!
When I first realized these successions, I nearly gave up on the idea, but then I thought just maybe I could use inheritance to gain access to the ComboBox. This would be tricky, and the DataGridViewComboBoxColumn and DataGridViewComboBoxCell would have to allow alternate object types to be used.
I created three classes, DropDownListColumn which inherits DataGridViewComboBoxColumn, DropDownListCell which inherits DataGridViewComboBoxCell, and DropDownListEditingControl which inherits DataGridViewComboBoxEditingControl which inherits ComboBox.
The DataGridViewComboBoxColumn exposes the CellTemplate property which gets or sets the object used in the DataGridView cells. This property is changed in the default constructor within my new class, DropDownListColumn.
Public Class DropDownListColumn
Inherits DataGridViewComboBoxColumn
Public Sub New()
'Set the type used in the DataGridView
Me.CellTemplate = New DropDownListCell
End Sub
End Class
The DataGridViewComboBoxCell�s EditType property returns the type of editing control used by the cell to edit the value. I override this property in my new class, DropDownListCell, and return the type DropDownListEditingControl. There is also the GetFormattedValue function which allows the ForeColor of the text in the cell to be altered. The ForeColor needs to be altered in the drop down list as well.
Public Class DropDownListCell
Inherits DataGridViewComboBoxCell
Public Overrides ReadOnly Property EditType() As Type
Get
' Return the type of the editing contol that
' the DropDownListCell uses.
Return GetType(DropDownListEditingControl)
End Get
End Property
Protected Overrides Function GetFormattedValue( _
ByVal value As Object, ByVal rowIndex As Integer, _
ByRef cellStyle As System.Windows.Forms.DataGridViewCellStyle, _
ByVal valueTypeConverter As System.ComponentModel.TypeConverter, _
ByVal formattedValueTypeConverter As _
System.ComponentModel.TypeConverter, _
ByVal context As _
System.Windows.Forms.DataGridViewDataErrorContexts) As Object
'Get object that is diplayed in the DataGridView cells
'with default formatting
Dim obj As Object = MyBase.GetFormattedValue( _
value, rowIndex, cellStyle, _
valueTypeConverter, formattedValueTypeConverter, _
context)
'If the text is prefixed with EXPIRED then make the font red
If Not IsNothing(obj) AndAlso obj.ToString.StartsWith("EXPIRED") Then
cellStyle.ForeColor = System.Drawing.Color.Red
End If
Return obj
End Function
End Class
The DataGridViewComboBoxEditingControl is the final class we need to inherit from. First, we need to override the default constructor to set a couple of properties. We need to set DrawMode to OwnerDrawFixed. This causes the DrawItem event to fire, allowing the developer to change the appearance of the list at runtime. We also need to set DropDownStyle to DropDownList, making the ComboBox a DropDownList. I could leave this property alone and set it in the properties page for the DropDownListColumn, but I would have to do this each time I use the control.
To change the BackColor and the ForeColor, we need to override OnDrawItem. Within the subroutine, we can use the System.Windows.Forms.DrawItemEventArgs to render the FillRectangle in either SystemColors.Window or SystemColors.ControlLight, two of my favorite colors. We can then look at the ToString method of the list item object to see if it is prefixed with EXPIRED. If it is, use a Color.Red SolidBrush, otherwise use a SystemColors.ControlText SolidBrush to render the text. The ToString method may need to be overridden in the list item's object class, or you may need to select another property to examine.
Public Class DropDownListEditingControl
Inherits DataGridViewComboBoxEditingControl
Public Sub New()
MyBase.New()
'This will cause the DrawItem event to raise,
'allowing changes to be made to the appearance
'at run time
Me.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed
'Make this a DropDownList
Me.DropDownStyle = ComboBoxStyle.DropDownList
End Sub
Protected Overrides Sub OnDrawItem( _
ByVal e As System.Windows.Forms.DrawItemEventArgs)
' Create a rectagle the size of the item container
Dim rec As New Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, _
e.Bounds.Height)
If Me.Enabled Then
'If the item is being pointed to highlight it
If (e.State And DrawItemState.Focus) = DrawItemState.Focus Then
e.Graphics.FillRectangle( _
New SolidBrush(System.Drawing.SystemColors.Highlight), rec)
'The next two clauses will cause the item backcolor to alternate
ElseIf (e.State And DrawItemState.ComboBoxEdit) = _
DrawItemState.ComboBoxEdit _
OrElse e.Index Mod 2 = 1 Then
e.Graphics.FillRectangle( _
New SolidBrush(System.Drawing.SystemColors.Window), rec)
Else
e.Graphics.FillRectangle( _
New SolidBrush(System.Drawing.SystemColors.ControlLight), rec)
End If
Else
'Grey out the box it is disablbed
e.Graphics.FillRectangle( _
New SolidBrush(System.Drawing.SystemColors.Control), rec)
End If
'If there is an item
If e.Index > -1 Then
Dim obj As Object = Me.Items(e.Index)
'If the item is selected highlight it
If (e.State And DrawItemState.Focus) = DrawItemState.Focus Then
Dim HighlightedText As _
New SolidBrush(System.Drawing.SystemColors.HighlightText)
e.Graphics.DrawString(obj.ToString, e.Font, _
HighlightedText, rec)
'If the item starts with EXPIRED make it red
ElseIf obj.ToString.StartsWith("EXPIRED") Then
Dim ExpireText As New SolidBrush(System.Drawing.Color.Red)
e.Graphics.DrawString(obj.ToString, e.Font, ExpireText, rec)
Else
Dim NormalText As New _
SolidBrush(System.Drawing.SystemColors.ControlText)
e.Graphics.DrawString(obj.ToString, e.Font, NormalText, rec)
End If
Else
Dim NormalText As New _
SolidBrush(System.Drawing.SystemColors.ControlText)
e.Graphics.DrawString("", e.Font, NormalText, rec)
End If
End Sub
End Class
There is not a lot of code to this technique, and it could be easily applied to other canned DataGridView column controls. Additionally, this technique gains you access to many methods, properties, and events otherwise unavailable. Just think of all the hub caps one could create.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 5 Oct 2006 Editor: Smitha Vijayan |
Copyright 2006 by mark.stratman Everything else Copyright © CodeProject, 1999-2009 Web22 | Advertise on the Code Project |