Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Buscar elemento en listbox (https://www.clubdelphi.com/foros/showthread.php?t=90260)

mblascog 05-05-2016 23:43:13

Buscar elemento en listbox
 
Buenas,
Estoy intentando encontrar la manera que según el contenido de un edit.txt se posicione el cursor en un listbox.
He hecho lo siguiente:

Código Delphi [-]
procedure Tpform.buscaChange(Sender: TObject);
begin
  if Lista.Items.IndexOf(busca.text) > 0 then
    Lista.ItemIndex := Lista.Items.IndexOf(busca.text);
end;

Pero este código posiciona el cursor siempre que la coincidencia sea exacta, y a mi me gustaría que se posicionara cuando coincida el inicio del elemento del listbox, es dir, si en el edit.txt escribo 'ab' se posicione al primer elemento que empieze por ab.
Estoy leyendo que no es posible. Si no es posible, hay algún componente que lo permita?

Gracias

AgustinOrtu 06-05-2016 00:39:05

En donde dice que no es posible?

Lo podes implementar "a mano", o podes buscar por "ComboBox incremental search".

En Delphi 7 creo que no esta implementado, pero en realidad el que lo implementa es el control ComboBox de Windows que la VCL envuelve, con enviar un mensaje usando la API de Windows lo podes lograr

La otra forma es implementarlo uno mismo

Debes recorrer los strings contenidos en tu combo, comparar cada uno con la cadena de texto que esta ingresada en el combo en ese momento, y si hay coincidencia parcial, poner ese elemento como seleccionado y cortar el bucle

Código Delphi [-]
uses
  StrUtils;

procedure TForm1.ComboBox1Change(Sender: TObject);
var
  I: Integer;
  AText, s: string;
begin
  AText := ComboBox1.Text;

  if AText = EmptyStr then
    Exit;

  for I := 0 to ComboBox1.Items.Count - 1 do
  begin
    s := ComboBox1.Items[i];
    if StartsText(AText, s) then
    begin
      ComboBox1.ItemIndex := I;
      ComboBox1.SelStart := Length(AText);
      ComboBox1.SelLength := Length(s) - Length(AText);
      Break;
    end;
  end;
end;

Creo que este es un inicio

Edito: Perdon, lei mal, hablas de TListBox, pero creo que el concepto es el mismo

mblascog 06-05-2016 09:04:06

Gracias AgustinOrtu. Creo que defiere un poco entre el ComboBox y el ListBox. SeltStart y SelLength no están implementadas en ListBox.
Había pensado en la implementación manual, y voy a hacerlo ahora, pero me da la sensación que debe ser lento, pues además de buscar si por el contenido del edit empieza algún elemento del listbox (ordenado), tienes que comprobar cuando se haya pasado, para no hacer todo el bucle

Neftali [Germán.Estévez] 06-05-2016 09:51:07

Con esto te debería valer:

Código Delphi [-]
var
  i, j: Integer;
begin
  j := -1;
  for i := 0 to (ListBox1.Count - 1) do begin
    if AnsiStrLIComp(PChar(ListBox1.Items[i]), PChar(Edit1.Text), Length(Edit1.Text))=0 then begin
      j := i;
      Break;
    end;
  end;
  ListBox1.ItemIndex := j;

Te selecciona el primero que coincida o no te selecciona ninguno si no hay elemento coincidente.

Si cambias AnsiStrLIComp (case-insensitive) por AnsiStrLComp (case-sensitive) conseguirás que distinga o no por may/min.

mblascog 06-05-2016 10:10:40

Muchas gracias, funciona perfecto, aunque para optimizarlo, ya que la lista contiene muchos ítems, está bien controlar que cuando se ha pasado de largo salga del bucle

mblascog 06-05-2016 11:52:51

Para optimizar había pensado con este if:

Código Delphi [-]
if copy(Listbox1.Items[i], 1, length(edit1.text) > edit1.text then
break

Pero no funciona, pues Ló es más grande que Lu, con esto quiero decir que, si por ejemplo busco Lucena no lo encuentra, dado que antes encuentra López y al ser mayor, sale del bucle

Neftali [Germán.Estévez] 06-05-2016 13:41:54

Cita:

Empezado por mblascog (Mensaje 504998)
Muchas gracias, funciona perfecto, aunque para optimizarlo, ya que la lista contiene muchos ítems, está bien controlar que cuando se ha pasado de largo salga del bucle

Creo que he puesto el break dentro del bucle.
:cool:


La franja horaria es GMT +2. Ahora son las 18:44:09.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi