Buscar en un listview y resaltar item

Iniciado por nolasco281, 22 Mayo 2015, 02:29 AM

0 Miembros y 2 Visitantes están viendo este tema.

nolasco281

Hola como estan.

La consulta que tengo es como buscar en un listiview(Control telerik) se como buscar en un control de winform de echo es el codigo que he modificado pero no se por que no me busca.

Este es el codigo que tengo
Código (vbnet) [Seleccionar]
Dim i As Integer
       'obtiene el número de elementos del componente
       For i = 0 To lvPagosProveedores.Items.Count
           'Obtiene el indice en base a 0 del elemento seleccionado
           lvPagosProveedores.SelectedIndex = i
           'verifica que el elemento selecionado del control sea igual al que esta escrito en el textBox
           If lvPagosProveedores.SelectedItem.Selected = txtBuscarPagoProvee.Text Then
               'Establece el nuevo indice del control
               lvPagosProveedores.SelectedIndex = i
               'lvPagosProveedores.Focus()
               Exit For
           Else
               RadMessageBox.Show(Me, "Ese codigo no existe", "Informacion",
                                     MessageBoxButtons.OK, RadMessageIcon.Info)
           End If


El problema es que no me busca bien siempre regresa al primer item si se fijan busco 5 pero siempre me muestra 1 en indice


Saludos.
Lo que se puede imaginar... se puede programar.

seba123neo

podes usar FindItemWithText para hacer una busqueda simple de texto.

Código (vb) [Seleccionar]
Dim item As ListViewItem = Nothing
item = Me.ListView1.FindItemWithText("texto a buscar", False, 0)

Me.ListView1.SelectedItems.Clear()

If item Is Nothing Then
MessageBox.Show("No se encontro.")
Else
item.Selected = True
item.EnsureVisible()
Me.ListView1.Select()
End If


saludos.
La característica extraordinaria de las leyes de la física es que se aplican en todos lados, sea que tú elijas o no creer en ellas. Lo bueno de las ciencias es que siempre tienen la verdad, quieras creerla o no.

Neil deGrasse Tyson

Eleкtro

#2
Cita de: seba123neo en 22 Mayo 2015, 04:10 AMpodes usar FindItemWithText para hacer una busqueda simple de texto.

El problema es que este control de terceros no tiene un método similar (o al menos yo desconozco que haya alguna función parecida a FindItemWithText de un Listview común).

Una forma de resolver el problema sería así:

Código (vbnet) [Seleccionar]
    ''' <remarks>
    ''' *****************************************************************
    ''' Snippet Title: Find Item Extended for Telerik RadListView.
    ''' Author       : Elektro
    ''' Date Modified: 22-May-2015
    ''' *****************************************************************
    ''' </remarks>
    ''' <summary>
    ''' Find and returns all the <see cref="ListViewDataItem"/> occurrences that matches the specified criteria.
    ''' </summary>
    ''' <typeparam name="ItemType">The <see cref="Type"/> of the data to find.</typeparam>
    ''' <param name="lv">The <see cref="RadListView"/>.</param>
    ''' <param name="itemIndex">The index of the item to search on.</param>
    ''' <param name="find">The data to find.</param>
    ''' <returns><see cref="IEnumerable(Of ListViewDataItem)"/>.</returns>
    Friend Shared Iterator Function FindItemEx(Of ItemType)(ByVal lv As RadListView,
                                                            ByVal itemIndex As Integer,
                                                            ByVal find As ItemType) As IEnumerable(Of ListViewDataItem)

        For Each lvItem As ListViewDataItem In lv.Items

            Dim item As Object = lvItem.Item(itemIndex)

            If (TypeOf item Is ItemType) AndAlso (DirectCast(item, ItemType).Equals(find)) Then
                Yield lvItem
            End If

        Next lvItem

    End Function


Modo de empleo:
Código (vbnet) [Seleccionar]
   Private Sub Button1_Click() Handles Button1.Click

       With lvPagosProveedores
           .Columns.Add("column1")
           .Columns.Add("column2")

           .Items.Add({"1", "2"})
           .Items.Add({"3", "4"})
           .Items.Add({5, 6})
           .Items.Add({5, 6})
           .Items.Add({True, False})
       End With

       Dim lvItems As IEnumerable(Of ListViewDataItem) =
           FindItemEx(Of Integer)(lv:=lvPagosProveedores, itemIndex:=0, find:=5)

       Select Case lvItems.Count

           Case Is = 0
               RadMessageBox.Show(lvPagosProveedores.FindForm,
                                  "Ese codigo no existe", "Informacion",
                                  MessageBoxButtons.OK, RadMessageIcon.Info)

           Case Else
               With lvPagosProveedores
                   .SuspendLayout()

                   .MultiSelect = True
                   .SelectedIndex = .Items.IndexOf(lvItems.Last)
                   .Select(lvItems.ToArray)
                   .Focus()

                   .ResumeLayout()
               End With

       End Select

   End Sub


Saludos








nolasco281

#3
Hola Elecktron, seba123neo

Muchas gracias a ambos por responder.

Para ser sincero no creo que lo hubiera resuelto.

Código (vbnet) [Seleccionar]
Dim lvItems As IEnumerable(Of ListViewDataItem) =
           FindItemEx(Of Integer)(lv:=lvPagosProveedores, itemIndex:=0, find:=5)


solo cambien en la parte de find por la entrada del textbox

Código (vbnet) [Seleccionar]
Dim lvItems As IEnumerable(Of ListViewDataItem) =
           FindItemEx(Of Integer)(lv:=lvPagosProveedores, itemIndex:=0, find:=txtBuscarPagoProvee.Text)


Te adjunto una imagen


Muchas gracias por el tiempo a ambos.

Aunque las gracias esa poco.

Saludos.

PD: Me llevo tiempo entender algunas cosas pero ya esta : ).
Lo que se puede imaginar... se puede programar.

Eleкtro

Cita de: nolasco281 en 22 Mayo 2015, 05:44 AMPara ser sincero no creo que lo hubiera resuelto.

1. La propiedad Selected es booleana e indica si el item está seleccionado... obviamente ibas muy mal encaminado por que aquí estás comparando True o False con un String:
Cita de: nolasco281 en 22 Mayo 2015, 02:29 AM
Código (vbnet,3) [Seleccionar]
...
'verifica que el elemento selecionado del control sea igual al que esta escrito en el textBox
If lvPagosProveedores.SelectedItem.Selected = txtBuscarPagoProvee.Text Then
...
(Usa IntelliSense para leer la descripción de cada miembro/propiedad).

2. Lo cierto es que a pesar de ese fallo el problema lo podrías haber resuelto sin ayuda, recuerda lo que te expliqué en otro post sobre la propiedad Key y la función FindItemByKey, puedes aplicar esa misma metodología a un RadListView, y eso solucionaría el problema, es decir, añades cada item con una 'Key' que contenga su código del pedido, y luego usas la función RadListView.FindItemByKey().

Saludos!








nolasco281

#5
Hola de hecho probé el findKey de ese método

Parecido a lo que a lo del otro post como mencionas

Pero en lo que me fije que cuando se agrega el item al listview se le agrega la llave, y en este caso muestro los datos en el listview con un Query a la BD no sé si aun así se le puede asignar una llave a los item del listview eso me confundió un poco, pero claro que lo probé por que hace la búsqueda y compara si existe o no, así que es casi lo mismo que mencionas.

Que seria esta parte:

Donde le agregas la llave al campo articulo.

Código (vbnet) [Seleccionar]
ElseIf Me.lvListaPedidos.FindItemByKey(key:=articulo.ToLower, searchVisibleItems:=True) IsNot Nothing Then
           RadMessageBox.Show("El articulo ya existe en la lista.", "", MessageBoxButtons.OK, RadMessageIcon.Error)

Else
           Dim lvItem As New ListViewDataItem(text:="", values:={articulo, cantidad, total}) With
       {.Key = articulo.ToLower}
           Me.lvListaPedidos.Items.Add(lvItem)
End If


En el caso de la busqueda deberia de asignar una llave por cada item a la columna no??
Oh antes de cargar los datos le asigno la llave?

Corrigeme si estoy mal en algo por favor.

Saludos.
Lo que se puede imaginar... se puede programar.

Eleкtro

#6
Cita de: nolasco281 en 22 Mayo 2015, 06:31 AMen este caso muestro los datos en el listview con un Query a la BD no sé si aun así se le puede asignar una llave a los item del listview eso me confundió un poco, pero claro que lo probé por que hace la búsqueda y compara si existe o no, así que es casi lo mismo que mencionas.

Uf, me ha costado un poco descubrir la respuesta a tu pregunta, cómo ya te dije no soy ningún gurú de Telerik, quizás el siguiente código se pueda simplificar (imagino que Telerik ofrecerá algo más "accesible" que estar leyendo la cantidad de items cada vez), he ido un poco a ciegas pero esto es lo que conseguí hacer:

Código (vbnet) [Seleccionar]
   ''' <summary>
   ''' Handles the <see cref="RadListView.ItemCreating"/> event of the <see cref="lvPagosProveedores"/> control.
   ''' </summary>
   ''' <param name="sender">The source of the event.</param>
   ''' <param name="e">The <see cref="ListViewItemCreatingEventArgs"/> instance containing the event data.</param>
   Private Sub LvPagosProveedores_ItemCreating(sender As Object, e As ListViewItemCreatingEventArgs) _
   Handles lvPagosProveedores.ItemCreating

       e.Item.Key = e.Item.Owner.Items.Item(e.Item.Owner.Items.Count - 1).Item(0).ToString

   End Sub


De esa manera lo que hago es asignar de forma automatiada la "key" a cada item que se añada al radlistview, a la "key" le asigno el mismo valor que la primera celda (.Item(0)) del item actual, que sería el "código de pedido" en tu caso.

Espero que te sirva.

Cita de: nolasco281 en 22 Mayo 2015, 06:31 AMEn el caso de la busqueda deberia de asignar una llave por cada item a la columna no??
Oh antes de cargar los datos le asigno la llave?

No te entendí bien, cómo ya digo el procedimiento es el mismo, añadir un item al radlistview, asignarle una llave a ese item, y buscar por la llave.

Intuyo que estás utilizando un datasource así que deberías aplicar una asignación de llaves automatizada como en el código que he mostrado, con eso debería funcionarte bien.

Saludos!








nolasco281

#7
Funciono también solo que primero hay que llenar el listview y después ejecutar el evento, si no muestra un error algo como esto Index was out of range.

Pero sirvió por medio de llaves.

Gracias sé que no eres un Guru de Telerik. (Aunque no lo creo)

Pero cualquier idea de cómo tratar de hacerlo se agradece enormemente

Muchas gracias de nuevo Eleкtro

Disculpa las molestias.

Saludos.

PD: uso un DateTable para no traer el nombre de las columnas de la BD pero funciona tambien por medio de llaves. : )))
Lo que se puede imaginar... se puede programar.