Solved

DataGridViewComboBoxColumn very slow

Posted on 2011-09-26
6
1,215 Views
Last Modified: 2013-12-17
Hello!

I have a DataGrid, with several columns. One of them is DataGridViewComboBoxColumn. I have a lot of items in this column - more than 1000 - and I need all of them. So grouping is not an option - all items must be there, users must be able to select from all.
The problem is, DataGridViewComboBoxColumn becomes painfully slow, when number of items is about 1000, and above. This issues is well known to Microsoft, it dates back to Visual Studio 2005: http://connect.microsoft.com/VisualStudio/feedback/details/117024/datagridviewcomboboxcolumn-responds-very-slow-compared-with-the-stand-alone-combobox-control.

The problem is still present in Visual Studio 2010. Any ideas how to solve this?
0
Comment
Question by:AntonioRodrigo
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
6 Comments
 
LVL 15

Accepted Solution

by:
x77 earned 500 total points
ID: 36711756
For large list of options, I use modified DataGridViewTextBoxCollumn to support Autocomplete.

To Validate value in list, it has property RestrictAutoComplete.
 
<DebuggerStepThrough()> _
Public NotInheritable Class DgvTextBoxCol
    Inherits DataGridViewTextBoxColumn
    Public AutoCompleteStringCollection As AutoCompleteStringCollection
    Public CharacterCasing As CharacterCasing
    Public RestrictAutoComplete As Boolean
    Public DrowDownWidth As Integer
    Private OldWidth As Integer

    Sub New()
        MyBase.New()
        CellTemplate = New Cell
    End Sub

    Protected Sub New (ByVal Cell As Cell)
        MyBase.New()
        CellTemplate = Cell
    End Sub

    Public Overrides Function Clone() As Object
        Dim c = DirectCast (MyBase.Clone(), DgvTextBoxCol)
        c.CharacterCasing = Me.CharacterCasing
        c.AutoCompleteStringCollection = Me.AutoCompleteStringCollection
        c.ValueType = MyBase.ValueType
'        c.RestrictAutoComplete = Me.RestrictAutoComplete
        Return c
    End Function

    Protected Class Cell
        Inherits DataGridViewTextBoxCell

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

            ' Set the value of the editing control to the current cell value.
            MyBase.InitializeEditingControl (rowIndex, initialFormattedValue, dataGridViewCellStyle)
            Dim col = DirectCast (OwningColumn, DgvTextBoxCol), Tb = DirectCast (DataGridView.EditingControl, TextBox)
            Tb.CharacterCasing = col.CharacterCasing
            If col.AutoCompleteStringCollection IsNot Nothing Then
                Autocomplete (Tb, col.AutoCompleteStringCollection)
                If col.DrowDownWidth > 0 Then col.OldWidth = col.Width : col.Width = col.DrowDownWidth
            End If
        End Sub

        Public Overrides Sub DetachEditingControl()
            MyBase.DetachEditingControl()
            DirectCast (DataGridView.EditingControl, TextBox).PasswordChar = Nothing
            Dim Tb = DirectCast (DataGridView.EditingControl, TextBox)
            If Tb.AutoCompleteCustomSource IsNot Nothing Then
                Dim col = DirectCast (OwningColumn, DgvTextBoxCol)
                If col.OldWidth > 0 Then col.Width = col.OldWidth
                Autocomplete (Tb, Nothing)
            End If
            Tb.CharacterCasing = System.Windows.Forms.CharacterCasing.Normal
        End Sub

        <DebuggerStepThrough()> _
        Public Overrides Function ParseFormattedValue (ByVal formattedValue As Object, _
                                                       ByVal cellStyle As DataGridViewCellStyle, _
                                                       ByVal formattedValueTypeConverter As TypeConverter, _
                                                       ByVal valueTypeConverter As TypeConverter) As Object
            Dim c = DirectCast (OwningColumn, DgvTextBoxCol)
            Dim v = MyBase.ParseFormattedValue(formattedValue, cellStyle, formattedValueTypeConverter, _
                                                valueTypeConverter)
            If v IsNot Nothing AndAlso c.RestrictAutoComplete AndAlso TypeOf formattedValue Is String Then
                Dim s = DirectCast (v, String).Trim
                If s.Length = 0 Then Return Nothing
                If c.AutoCompleteStringCollection.Contains (s) = False Then _
                    Throw New FormatException ("Valor no contenido en lista de valores válidos")
                Return s
            End If
            Return v
        End Function
    End Class
End Class

Open in new window


This class supports also CharacterCasing.
You can set also DrowDownWidth.

I use it with list of about 1500 values with no problem.
0
 
LVL 15

Expert Comment

by:x77
ID: 36712218
I missing the Autocomplete, I declare it on a module:

Sub Autocomplete(ByVal Tb As TextBox, ByVal Ac As AutoCompleteStringCollection)
    If Ac Is Nothing Then
        Tb.AutoCompleteMode = Windows.Forms.AutoCompleteMode.None
        Tb.AutoCompleteSource = Windows.Forms.AutoCompleteSource.None
    Else
       Tb.AutoCompleteMode = Windows.Forms.AutoCompleteMode.Suggest
       Tb.AutoCompleteSource = Windows.Forms.AutoCompleteSource.CustomSource
    End If
    Tb.AutoCompleteCustomSource = Ac
End Sub
0
 

Author Comment

by:AntonioRodrigo
ID: 36716023
Is there a way to import ID in AutoCompleteStringCollection?

So, f.e.: I have a data table with column "ID" and column "Name". I want to display a "Name" column in autocomplete, but I also need an ID as information in the background for each row.

WIth DataGridViewComboBoxColumn this is solved as setting 'ValueMember' and 'DisplayMember' property.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:AntonioRodrigo
ID: 36716548
Is it possible to display drop down pop up with click on the text box?

I mean - I don't type anything in the text box, just click on it and drop down with items is opened.
0
 
LVL 15

Expert Comment

by:x77
ID: 36719573
The advantage of autocomplete is that, you press "A" by sample, then it show members that starts with "A", now you can type more chars and you can see the filtered result.

The combobox is more dificult to use.
It isn´t the best option for a lot of items.

Some times, I build an aditional Dialog to filter with "like" operator ( id like '%value%') or String.Contains.
By sample,  we need a Id and I don´nt know about this key, then I show a Dialog with a DGV or ListView that shows Id and Description with autofilter by id and description..

The user can need a Valve on System C11, the key is like xxC11Gxxx.
You can use DoubleClick on Dgv Field to shows Selection Dialog.
Most intuitive is a Button with "..." at right of your field  to show Selection dialog.

To build an autocomplete string collection, fill a list(of String) with values, then use

   MyAutoCompleteStringCollection.addrange(list.toarray)

You can use LinQ to build the array. I prefer the clasic method.
Note that you can use same collection on more than one field.
0
 

Author Closing Comment

by:AntonioRodrigo
ID: 36813207
The way to solve the problem is correct - use another control instead of painfully slow DataGridViewComboBoxColumn. I've come at the end to use ListBox on top of my DataGridView cell - which is very fast. Your idea was the first step to find solution.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
The viewer will learn how to use and create keystrokes in Netbeans IDE 8.0 for Windows.

696 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question