problema con evento drawitem en listbox

Moderador: yalmar

Foro cerrado salvo peticion.

problema con evento drawitem en listbox

Notapor neg14 » Lun May 26, 2008 2:37 pm

Buenas:

Tengo un ListBox con una serie de elementos ordenados Alfabeticamente.
Los elementos del Listbox pueden estar en una de esta dos situaciones

1- Elemento Inhabilitado: Ha sido "tomado" anteriormente (incluido en otra estructura) y no puede volver a ser "tomado"

2 -Elemento Habilitado: Puede ser "tomado"

Para distinguirlos visualmente he considerado diferenciarlos mediante el color del texto.

Gris: InHabilitado

Rojo: Habilitado.

Para ello he modificado la Proiedad del ListBox a Style = LBOWERDRAWFIXED y asi redibujar el listBox con el evento DRAWITEM cada vez que se opere con um elemento del ListBox.

En el Porcedimiento ListBoxDrawItem he implementado el codigo:


Código: Seleccionar todo
  1. Código:

  2.  

  3. void __fastcall   *********::ListBoxDrawItem(TWinControl *Control,

  4.       int Index, TRect &Rect, TOwnerDrawState State)

  5. {

  6.  

  7.  

  8.        //EstadEquipos[] es un vector de booleans que indicara si el equipo          

  9.        //que esta en la posicion que se corresponde con el indice esyta

  10.        //Habilitado o no.

  11.        //Si esta Seleccionado cambiar color

  12.        if (EstadEquipos[Index]== false)

  13.            {

  14.              ListHistEquip->Canvas->FillRect(Rect);

  15.              ListHistEquip->Canvas->Font->Color=clDkGray;//Color  texto gris

  16.              ListHistEquip->Canvas->TextOut(Rect.Left,Rect.Top,ListHistEquip->Items->Strings[Index]);

  17.            }

  18.            else

  19.            {

  20.              //Si el Item esta seleccionado

  21.              if (State.Contains(odSelected))

  22.              {

  23.               ListHistEquip->Canvas->FillRect(Rect);

  24.               ListHistEquip->Canvas->Font->Color=clWhite;  //Color  texto blanco

  25.               ListHistEquip->Canvas->TextOut(Rect.Left,Rect.Top,ListHistEquip->Items->Strings[Index]);

  26.              }

  27.              else

  28.              {

  29.               ListHistEquip->Canvas->FillRect(Rect);

  30.               ListHistEquip->Canvas->Font->Color=clRed;  //Color texto Rojo

  31.               ListHistEquip->Canvas->TextOut(Rect.Left,Rect.Top,ListHistEquip->Items->Strings[Index]);

  32.              }

  33.            }

  34. }

  35.  

  36.  



Hasta Aqui todo perfecto..

Mi problema surge cuando quiero que al pulsar una tecla (una letra) el item seleccionado (el que aparezca resaltado con la franja azul caracteristica) seal el primero que comienze por la letra pulsada.

Para ello en el evento KEYDOWN del ListBox he incluido este codigo:

Código:
Código: Seleccionar todo
  1.  

  2.  

  3.    Char L;

  4.     for (int i=0; i<ListEquipJorn>Count;i++)

  5.       {

  6.          L = ListEquipJorn->Items->Strings[i][1];

  7.          if (L==Key &&  EstadEquipos[i])

  8.             {

  9.              ListEquipJorn->ItemIndex = i; //Selecciono item (Primero que empieza por la letra pulsada

  10.               break;

  11.              }

  12.         }

  13.  

  14.  



!!!! SIEMPRE EL ITEM SELECCIONADO ES EL SEGUNDO ELEMENTO QUE COMIENZA POR LA LETRA PULSADA !!! Crying or Very sad

He seguido el programa paso a paso y este es su funcionamiento:

1 . Supongamos que la tecla pulsada es la G y el primer elemento que empieza por la letra G esta en la posicion 15.

2 . El Evento KEYDOWN funciona perfectamente al llegar a la posicion 15 la reconoce como primer elemento que empieza por G y lo selecciona:
ListEquipJorn->ItemIndex = i; sale del bucle.sale del evento.

3. Redibuja el ListBox: Aqui es donde no entiendo el funcionamiento

a) Entra en el evento DrawItem con Index = 15 lo reconoce como selecionado sale del evente

b) Vuelve a entrar en el evento con Index =16 ?? lo reconoce como no selecionado sale del evento

c) Vuelve a entrar en el evento como index =16 ?? lo reconoce como no selecionado sale del evento


c) Vuelve a entrar en el evento como index =15 ?? lo reconoce como NO selecionado sale del evento


d) Vuelve a entrar en el evento como index =16 ?? lo reconoce como SI selecionado sale del evento


el segundo elemento que comienza por G (index =16 ) esta seleccionado


Alguna Idea Gracias
neg14
Novato
Novato
 
Mensajes: 11
Registrado: Dom Jul 15, 2007 3:31 am


Re: problema con evento drawitem en listbox

Notapor ivancp » Lun May 26, 2008 9:45 pm

No conozco mucho de C++ Builder pero creo que algunas reglas de los Common Controls se aplican para todos.

Me parece que cuando cambias el item seleccionado invoca a otro vento (Item change) al que curiosamente se invoca dos veces (una para el item que pierde el foco y otro para el item que lo va a poseer).

Revisa si tienes por ahí algún evento relacionado con el cambio del ítem.

Si no es así entonces cambia la linea que contiene break; por return; si es que la funcion retorna algo entonces ponle return <tipo develto>;
Imagen @latindev | Mi Blog
Por favor lee las reglas del foro
Avatar de Usuario
ivancp
Colaborador
Colaborador
 
Mensajes: 680
Registrado: Jue Sep 06, 2007 12:58 pm


Re: problema con evento drawitem en listbox

Notapor neg14 » Jue May 29, 2008 12:04 pm

Buenas:

Cuando envie la consulta anterior creia que el problema (Dentro de un Listbox cuyos elementos estan ordenados alfabeticamente al pulsar una tecla alfanumerica el item que me seleccionaba era siempre el segundo del grupo de items que empezaban por la tecla pulsada..nunca el primero) era debido a que habia manipulado el evento DrawItem del Listbox.
La realidad es que cualquier listbox sin manipular que contenga un lista ordenada alfabeticamente de elementos al pulsar una tecla alfanumerica siempre se posiciona en el segundo elemento del grupo de elementos que comienzen por la misma letra (a mi os aseguro que me pasa) .

Código: Seleccionar todo
  1.  

  2.  

  3. TStringList  *Lista  = New TStringList

  4.  

  5.      Lista->Add("A")

  6.      Lista->Add("AB")  

  7.      Lista->Add("AC")

  8.      Lista->Add("B")

  9.      Lista->Add("BA")

  10.      Lista->Add("C")

  11.      ...

  12.  

  13.      Lista->Sorted;

  14.  

  15.  

  16.      for (int i=0;i<Lista>Count;i++)

  17.        {

  18.            ListBox1 ->Items->Text = Lista->Text

  19.        }

  20.  




Alguien sabe porque y como hacer que la posicion sea el primeros del grupo.
neg14
Novato
Novato
 
Mensajes: 11
Registrado: Dom Jul 15, 2007 3:31 am


    

Volver a C++ Builder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados