Solved

DataGridViewComboBoxColumn very slow

Posted on 2011-09-26
6
1,194 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
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

 

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: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

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

Suggested Solutions

Welcome my friends to the second instalment and follow-up to our Minify and Concatenate Your Scripts and Stylesheets (http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/A_4334-Minify-and-Concatenate-Your-Scripts-and-Stylesheets.html)…
This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.

732 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