Public Class BetterComboBox
Inherits ComboBox
Public Event SelectedIndexChanging As System.ComponentModel.CancelEventHandler 'Create a new event
Private WithEvents FadingWorker As New System.ComponentModel.BackgroundWorker
Private _lastIndex As Integer = -1
Private Const _fade As Double = 17
Private Const _fadeInterval As Double = 150
<System.ComponentModel.Browsable(False)>
Public ReadOnly Property LastIndex As Integer
Get
Return _lastIndex
End Get
End Property
Public Sub New()
MyBase.New()
_lastIndex = -1 'Initialise the last index as the default first index.
FadingWorker.WorkerReportsProgress = True
FadingWorker.WorkerSupportsCancellation = True
End Sub
Protected Overridable Sub OnSelectedIndexChanging(e As System.ComponentModel.CancelEventArgs)
RaiseEvent SelectedIndexChanging(Me, e) 'Raise the new event
End Sub
Protected Overrides Sub OnSelectedIndexChanged(e As System.EventArgs)
If _lastIndex <> SelectedIndex Then
Dim cancelEventArgs As New System.ComponentModel.CancelEventArgs()
OnSelectedIndexChanging(cancelEventArgs) 'Raise the new event
If cancelEventArgs.Cancel = False Then 'Check the response from the event
_lastIndex = SelectedIndex 'Save the index change
BackColor = Color.FromArgb(0, &HFF, 0) 'Change BG color to green
If Not FadingWorker.IsBusy Then 'Check the worker isnt already started
FadingWorker.RunWorkerAsync(Me) 'Start the worker
End If
MyBase.OnSelectedIndexChanged(e) 'Raise the normal event
Else
BackColor = Color.FromArgb(&HFF, 0, 0) 'Change BG color to red
If Not FadingWorker.IsBusy Then 'Check the worker isnt already started
FadingWorker.RunWorkerAsync(Me) 'Start the worker
End If
SelectedIndex = _lastIndex 'undo the index change
End If
End If
End Sub
Private Sub FadingWorker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles FadingWorker.DoWork
Dim worker As System.ComponentModel.BackgroundWorker = CType(sender, System.ComponentModel.BackgroundWorker)
While Not worker.CancellationPending 'Check the worker wasn't cancelled during progress reporting
System.Threading.Thread.Sleep(_fadeInterval) ' Wait N milliseconds
If Not worker.CancellationPending Then 'Check the worker wasn't cancelled during the delay
FadingWorker.ReportProgress(0, e.Argument) ' Signal the main thread to adjust the color
End If
End While
End Sub
Private Sub FadingWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles FadingWorker.ProgressChanged
Dim cb As BetterComboBox = CType(e.UserState, BetterComboBox)
' Code that fades the BackgroundColor RGB value here
If r = g = b = &HFF Then 'Check if the BackColor has reached white
FadingWorker.CancelAsync() 'Cancel the BackgroundWorker
End If
End Sub
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
'Use this to wait for the background worker to be die before disposing
If Not Me.IsDisposed Then
If disposing Then
'Free managed resources here
End If
'Free unmanaged resources here
End If
MyBase.Dispose(disposing)
End Sub
End Class