2012-02-21 18 views
7

Tengo un problema con el comportamiento de autocompletar de los cuadros combinados en VB.NET (con .NET framework 2.0).ComboBox de VB.NET - Comportamiento de autocompletado para los valores numéricos

estoy utilizando un cuadro combinado que escribir numéricos valores, y su lista desplegable para sugerir posibles numéricos valores. Esta lista está ordenada en orden ascendente, por ejemplo {"10", "92", "9000", "9001"}.

Las propiedades combobox se establecen de la siguiente manera:

  • AutoCompleteMode: SuggestAppend
  • AutoCompleteSource: ListItems
  • DropDownStyle: desplegable
  • Ordenada: Falso

la lista desplegable es simplemente lleno de esta manera:

  • myCombobox.Items.Add ("10")
  • myCombobox.Items.Add ("92")
  • myCombobox.Items.Add ("9000")
  • myCombobox.Items.Add (" 9001 ")

Cuando no escribo nada, el orden de los valores de la lista DropDown es correcto, en orden original/ascendente. Sin embargo, cuando empiezo a escribir algo, los valores sugeridos en la lista DropDown se ordenan (alfanuméricamente): si escribo "9", la lista de sugerencias se convierte en {"9000", "9001", "92"}.

Me gustaría evitar que este comportamiento obtenga los valores de la lista en el orden original/ascendente. No puedo entender cómo ...

Un posible problema sería rellenar con ceros los valores de la lista, p. {"0010", "0092", "9000", "9001"} pero me gustaría evitar esto.

Editar:

Como sugiere bendataclear, se puede utilizar un cuadro de lista para mostrar las sugerencias. Esto funcionará para listas pequeñas pero no se adapta bien a listas grandes. Puede ser útil para algunas aplicaciones. Basado en el código dado por bendataclear, me hizo trabajar de esta manera:

Private Sub ComboBox1_KeyUp(sender As System.Object, e As System.Windows.Forms.KeyEventArgs) Handles ComboBox1.KeyUp

Dim cursorPos As Integer = ComboBox1.SelectionStart 

    ListBox1.Items.Clear() 

    For Each s In ComboBox1.Items 
     If s.StartsWith(ComboBox1.Text) Then 
      ListBox1.Items.Add(s) 
     End If 
    Next 

    If ListBox1.Items.Count > 0 And ComboBox1.Text.Length > 0 Then 
     ComboBox1.Text = ListBox1.Items(0) 
     ComboBox1.SelectionStart = cursorPos 
     ComboBox1.SelectionLength = 0 
    End If 

End Sub 

El código no ha sido probado a fondo y se puede mejorar, pero la idea principal es que hay.

Edición 2:

Usando DataGridView conduce a un mejor rendimiento; fue suficiente para mí. Gracias bendataclear.

Sólo por curiosidad, cualquier otra respuesta es bienvenida :)

Respuesta

3

parece ser un problema cuando el cuadro combinado muestra los datos, ya que incluso si se establece una fuente personalizada que reordena alfabéticamente:

ComboBox1.Items.Add("10") 
ComboBox1.Items.Add("92") 
ComboBox1.Items.Add("9000") 
ComboBox1.Items.Add("9001") 

ComboBox1.AutoCompleteCustomSource.Add("10") 
ComboBox1.AutoCompleteCustomSource.Add("92") 
ComboBox1.AutoCompleteCustomSource.Add("9000") 
ComboBox1.AutoCompleteCustomSource.Add("9001") 

ComboBox1.AutoCompleteSource = AutoCompleteSource.CustomSource 

Creo que la única manera en que puedo pensar es crear su propia autocompletar algo así (no probado):

Dim cbotxt As String = ComboBox1.Text 
Dim key As String 

key = ChrW(e.KeyCode) 


ListBox1.Items.Clear() 

For Each i In ComboBox1.Items 

    Dim s As String = i.ToString() 

    If s.StartsWith(ComboBox1.Text & key) Then 

     ListBox1.Items.Add(s) 


    End If 

Next 

If ListBox1.Items.Count > 0 Then 
    ListBox1.Visible = True 
    ComboBox1.Text = ListBox1.Items(0) 

End If 

Editar:

Un buen enfoque para muchos artículos (estoy usando para 10000 + en una aplicación):

Primer cambio de un cuadro de lista a un DataGridView. declarará una lista de cadenas y se llenan de valores que desea autocompletar

Dim Numberlist as List<Of String> 

' Fill List using Numberlist.Add("String") 

Luego, en la propiedad de texto del cambio:

Filter = NumberList.FindAll(AddressOf checkNum) 

DataGridView1.DataSource = Filter 

y añadir la función para comprobar las cuerdas.

Function checkNum(ByVal b As String) As Boolean 

    If b.StartsWith(ComboBox1.Text) Then 
     Return True 
    Else 
     Return False 
    End If 

End Function 

Este método se ejecuta en mi máquina con 10k elementos más rápido de lo que puedo escribir.

+0

Gracias bendataclear. Esa es de hecho una forma de proceder. Sin embargo, se vuelve lento cuando crece la lista de elementos. Uno podría quizás usar mapas hash para construir previamente todas las listas posibles de elementos dependiendo del texto ingresado en el cuadro combinado, y así evitar pasar por toda la lista cada vez. Me resulta sorprendente que no pueda encontrar una forma más sencilla ... He agregado su solución a la pregunta. – DevelBD

+0

Agregado para responder – bendataclear

+0

Eso funciona. Las cadenas deben estar envueltas en una clase personalizada, de lo contrario, solo DataGridView mostrará la longitud de la cadena (ver http://stackoverflow.com/questions/479329/how-to-bind-a-string-list-to-a -cuadrícula de datos). Funciona bien para 10k artículos, y es razonablemente rápido para 100k artículos en mi computadora. ¡Gracias! – DevelBD

Cuestiones relacionadas