Requirement
Consider this, a list of Students and their overall performance. For the sake of this example, I will simply rate the performance at two levels
- 80% and above
- below 80%
A little about the Combobox Item rendering
Listitems in a combobox are rendered in one of two ways - an unselected listitem and a selected listitem.Since we would like to render the Student Listitems based on the performance factor at two levels, we will require a total of four color combinations -
- Students whose overall performance meets or exceeds 80%
Normal unselected
Selected
- Students whose overall performance is below 80%
Normal unselected
Selected
Lets dig in
Having defined the colors that we can use for rendering the listitems, here are the steps that are required
- Change the DrawMode property of the Combobox to OwnerDrawVariable. The default value is Normal.
- Handle the MeasureItem event of the Combobox. This allows for manipulating the size of each Listitem. In this current example, I have simply set a fixed height and width, however based on the value of e.Index and its corresponding Listitem element, you can change these values if you wish to render the Listitems differently.
Private Sub cmbStudents_MeasureItem(ByVal sender As Object, ByVal e As System.Windows.Forms.MeasureItemEventArgs) _
Handles cmbStudents.MeasureItem
e.ItemHeight = 18 'Pick this based on desired height of the listitem
e.ItemWidth = cmbStudents.Width
End Sub
- Handle the DrawItem event of the Combobox. Like the event name suggests, this event allows you to perform a custom draw of the Listitem every time the Listitem is displayed. For our example, it is sufficient to know that this event is fired each time a user expands the Combobox to view a list of items as well runs his mouse over the expanded list resulting in a hover selection of that listitem.
Private Sub cmbStudents_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) _
Handles cmbStudents.DrawItem
If e.Index < 0 Then
Exit Sub
End If
'Get the Student object that needs to be rendered using the e.Index
Dim oStudent As Student = CType(cmbStudents.Items(e.Index), Student)
Dim DisplayStr As String = oStudent.Name
Dim r As RectangleF = New RectangleF(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height)
If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
If oStudent.OverallPerformanceScore > 80 Then
e.Graphics.FillRectangle(Brushes.Lavender, r)
e.Graphics.DrawString(DisplayStr, e.Font, System.Drawing.Brushes.Blue, r)
Else
e.Graphics.FillRectangle(Brushes.AntiqueWhite, r)
e.Graphics.DrawString(DisplayStr, e.Font, System.Drawing.Brushes.Red, r)
End If
Else
If oStudent.OverallPerformanceScore > 80 Then
e.Graphics.FillRectangle(Brushes.GhostWhite, r)
e.Graphics.DrawString(DisplayStr, e.Font, System.Drawing.Brushes.Blue, r)
Else
e.Graphics.FillRectangle(Brushes.SeaShell, r)
e.Graphics.DrawString(DisplayStr, e.Font, System.Drawing.Brushes.Red, r)
End If
End If
' Draw the focus rectangle if mouse hovers over the item.
e.DrawFocusRectangle()
End Sub
The Result
Student Class Listing
Private Class Student
Private _Name As String
Private _OverallPerformanceScore As Double
Public Sub New(ByVal Name As String, ByVal OverallPerformanceScore As Double)
_Name = Name
_OverallPerformanceScore = OverallPerformanceScore
End Sub
Public ReadOnly Property Name() As String
Get
Return _Name
End Get
End Property
Public ReadOnly Property OverallPerformanceScore() As Double
Get
Return _OverallPerformanceScore
End Get
End Property
Public Overrides Function ToString() As String
Return Name
End Function
End Class
No comments:
Post a Comment