Custom DataGridViewComboBoxColumn very slow

Hello,

I've created a custom DataGridViewColumn. I've done this because DataGridViewComboBoxColumn becomes very slow, when dealing with more than 1000 items. My solution was working OK (very fast with thousands of items) as long as I didn't set AutoCompleteMode and AutoCompleteSource. When I did this, my custom column also become very slow on opening, almost same as Microsofts DataGridViewComboBoxColumn. Any idea how to solve this?

Here's my code (basically it's rewritten from this example: http://msdn.microsoft.com/en-us/library/7tas5c80.aspx)


Public Class DataGridViewComboBoxColumnCustom
    Inherits DataGridViewColumn

    Public Property AutoCompleteMode As AutoCompleteMode
        Get
            Return m_AutoCompleteMode
        End Get
        Set(ByVal value As AutoCompleteMode)
            m_AutoCompleteMode = value
        End Set
    End Property
    Private m_AutoCompleteMode As AutoCompleteMode

    Public Property AutoCompleteSource As AutoCompleteSource
        Get
            Return m_AutoCompleteSource
        End Get
        Set(ByVal value As AutoCompleteSource)
            m_AutoCompleteSource = value
        End Set
    End Property
    Private m_AutoCompleteSource As AutoCompleteSource

    Public Property DataSource() As BindingSource
        Get
            Return m_DataSource
        End Get
        Set(ByVal value As BindingSource)
            m_DataSource = value
        End Set
    End Property
    Private m_DataSource As BindingSource

    Public Property DisplayMember() As String
        Get            
            Return m_DisplayMember
        End Get
        Set(ByVal value As String)
            m_DisplayMember = value
        End Set
    End Property
    Private m_DisplayMember As String

    Public Property ValueMember() As String
        Get
            Return m_ValueMember
        End Get
        Set(ByVal value As String)
            m_ValueMember = value
        End Set
    End Property
    Private m_ValueMember As String

    Public Sub New()
        MyBase.New(New ComboBoxCell())        

    End Sub

    Public Overrides Property CellTemplate() As DataGridViewCell
        Get
            Return MyBase.CellTemplate
        End Get
        Set(ByVal value As DataGridViewCell)
            MyBase.CellTemplate = value
        End Set
    End Property

End Class


Public Class ComboBoxCell
    Inherits DataGridViewTextBoxCell

    Private WithEvents _ctl As ComboBoxEditingControl

    Public Sub New()
        MyBase.New()        
    End Sub


    Private Sub _ctl_Leave(ByVal sender As Object, ByVal e As EventArgs) Handles _ctl.Leave
        If DirectCast(sender, ComboBox).SelectedItem Is Nothing Then
            Return
        End If
        Me.DataGridView.CurrentCell.Value = (DirectCast(DirectCast(sender, ComboBox).SelectedItem, System.Data.DataRowView).Row).ItemArray(1).ToString()
    End Sub

    Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, ByVal initialFormattedValue As Object, ByVal dataGridViewCellStyle As DataGridViewCellStyle)
        MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle)

        _ctl = TryCast(DataGridView.EditingControl, ComboBoxEditingControl)

        Dim col As DataGridViewComboBoxColumnCustom = TryCast(Me.OwningColumn, DataGridViewComboBoxColumnCustom)

        _ctl.DataSource = col.DataSource
        _ctl.DisplayMember = col.DisplayMember
        _ctl.ValueMember = col.ValueMember
        _ctl.AutoCompleteMode = col.AutoCompleteMode
        _ctl.AutoCompleteSource = col.AutoCompleteSource

   
        Dim i As Integer = 0
        For Each item As Object In _ctl.Items
            If (DirectCast(item, System.Data.DataRowView).Row).ItemArray(1).ToString() = Me.DataGridView.CurrentCell.Value.ToString() Then
                _ctl.SelectedIndex = i
                Exit For
            End If
            i += 1
        Next
    End Sub

    Public Overrides ReadOnly Property EditType() As Type
        Get
            Return GetType(ComboBoxEditingControl)
        End Get
    End Property

    Public Overrides ReadOnly Property ValueType() As Type
        Get
            Return GetType(String)
        End Get
    End Property
End Class


Public Class ComboBoxEditingControl
    Inherits ComboBox
    Implements IDataGridViewEditingControl
    Private dataGridView As DataGridView
    Private valueChanged As Boolean = False
    Private rowIndex As Integer


    Public Sub New()
    End Sub


    Public Property EditingControlFormattedValue As Object Implements IDataGridViewEditingControl.EditingControlFormattedValue
        Get
            Return Me.ValueMember.ToString()
        End Get
        Set(ByVal value As Object)
            Me.ValueMember = value.ToString()
        End Set
    End Property

    Public Function GetEditingControlFormattedValue(ByVal context As DataGridViewDataErrorContexts) As Object Implements IDataGridViewEditingControl.GetEditingControlFormattedValue
        Return EditingControlFormattedValue
    End Function


    Public Sub ApplyCellStyleToEditingControl(ByVal dataGridViewCellStyle As DataGridViewCellStyle) Implements IDataGridViewEditingControl.ApplyCellStyleToEditingControl
        Me.Font = dataGridViewCellStyle.Font
    End Sub

    Public Property EditingControlRowIndex() As Integer Implements IDataGridViewEditingControl.EditingControlRowIndex
        Get
            Return rowIndex
        End Get
        Set(ByVal value As Integer)
            rowIndex = value
        End Set
    End Property

    Public Function EditingControlWantsInputKey(ByVal keyData As Keys, ByVal dataGridViewWantsInputKey As Boolean) As Boolean Implements IDataGridViewEditingControl.EditingControlWantsInputKey
        ' Let the ComboBox handle the keys listed.
        Select Case keyData And Keys.KeyCode
            Case Keys.Left, Keys.Up, Keys.Down, Keys.Right, Keys.Home, Keys.[End], _
             Keys.PageDown, Keys.PageUp
                Return True
            Case Else
                Return Not dataGridViewWantsInputKey
        End Select
    End Function

    Public Sub PrepareEditingControlForEdit(ByVal selectAll As Boolean) Implements IDataGridViewEditingControl.PrepareEditingControlForEdit

    End Sub

    Public ReadOnly Property RepositionEditingControlOnValueChange() As Boolean Implements IDataGridViewEditingControl.RepositionEditingControlOnValueChange
        Get
            Return False
        End Get
    End Property

    Public Property EditingControlDataGridView() As DataGridView Implements IDataGridViewEditingControl.EditingControlDataGridView
        Get
            Return dataGridView
        End Get
        Set(ByVal value As DataGridView)
            dataGridView = value
        End Set
    End Property

    Public Property EditingControlValueChanged() As Boolean Implements IDataGridViewEditingControl.EditingControlValueChanged
        Get
            Return valueChanged
        End Get
        Set(ByVal value As Boolean)
            valueChanged = value
        End Set
    End Property

    Public ReadOnly Property EditingPanelCursor() As Cursor Implements IDataGridViewEditingControl.EditingPanelCursor
        Get
            Return MyBase.Cursor
        End Get
    End Property

    Protected Overrides Sub OnValueMemberChanged(ByVal e As EventArgs)
        valueChanged = True
        Me.EditingControlDataGridView.NotifyCurrentCellDirty(True)
        MyBase.OnValueMemberChanged(e)
    End Sub
End Class


AntonioRodrigoAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
rerardConnect With a Mentor Commented:
Did you turn off autocomplete just due to performance or do you require that all the items are displayed?

I have a similar situation except my box can have up to 100k items in it, this solution has worked very well for me:
http://www.asp.net/ajaxlibrary/AjaxControlToolkitSampleSite/autocomplete/autocomplete.aspx

It offers similar functionality to the google autocomplete search and it is very fast with large datasets since only a small number of results are returned at a time.  I usually have it do just the top 20 but you can configure it however you want.
0
 
AntonioRodrigoAuthor Commented:
Sorry, I've forgot to mention that I am using WIndows Forms.
0
 
mlmccCommented:
This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.
0
All Courses

From novice to tech pro — start learning today.