| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
Publicado: Jue 03 May, 2007 12:28 pm Asunto: ListView: No lo entiendo |
|
|
A ver: tengo el ListView de la imagen. En el evento OnSelectItem tengo este código:
| Código: | void __fastcall TfGenRec::InfRecSelectItem(TObject *Sender, TListItem *Item, bool Selected)
{
pItem = NULL;
if (!Selected)
return;
else
pItem = Item;
} |
Sin embargo, si como está la imagen con el primer ítem seleccionado pregunto el valor de pItem->Caption, ¡me responde con semestrales! Siempre me da el ítem inferior al que está seleccionado. ¿Alguna sugerencia? Me hace falta para poder modificar el contenido de la segunda columna (Texto). _________________ Un saludo
Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA) |
|
| Volver arriba |
|
 |
Buildero Master


Registrado: 23 Dic 2003Mensajes: 523Ubicación: Puebla, México
|
Publicado: Jue 03 May, 2007 4:44 pm Asunto: |
|
|
Que raro Angel, he hecho una prueba con el código que has puesto y a mi si me presenta el caption correcto.
He declarado una variable privada de tipo ListItem y verifico el caption a través de un mensaje
Aqui la declaración de la clase
| Código: |
class TForm1 : public TForm
{
__published: // IDE-managed Components
TListView *ListView1;
TButton *Button1;
void __fastcall ListView1SelectItem(TObject *Sender, TListItem *Item,
bool Selected);
void __fastcall Button1Click(TObject *Sender);
private: // User declarations
TListItem *pItem;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
|
Y aquí la implementación
| Código: | void __fastcall TForm1::ListView1SelectItem(TObject *Sender,
TListItem *Item, bool Selected)
{
pItem = NULL;
if (!Selected)
return;
else
pItem = Item;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ShowMessage(pItem->Caption);
} |
Saludos! _________________ Quien hace una pregunta teme parecer un ignorante durante cinco minutos, quien no pregunta se mantiene ignorante toda la vida. |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
Publicado: Vie 04 May, 2007 8:50 am Asunto: |
|
|
Más o menos es el código que tenía puesto. A ver: el ListView es el que hay arriba
Tengo puesto este código. Para definir pItem:
| Código: | class TfGenRec : public TForm
{
__published: // IDE-managed Components
void __fastcall InfRecSelectItem(TObject *Sender, TListItem *Item, bool Selected);
void __fastcall InfRecDblClick(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TfGenRec(TComponent* Owner);
int nItem;
TListColumn *pColumn;
TListItem *pItem;
}; |
Y para "manejarlo"
| Código: | void __fastcall TfGenRec::InfRecSelectItem(TObject *Sender, TListItem *Item, bool Selected)
{
pItem = NULL;
if (!Selected)
return;
else
{
pItem = Item;
if (UpperCase(pItem->Caption) == "TOTALES");
pItem = NULL;
}
}
//---------------------------------------------------------------------------
void __fastcall TfGenRec::InfRecDblClick(TObject *Sender)
{
AnsiString cLiteral;
if (pItem != NULL)
{
cLiteral = pItem->SubItems->Strings[0];
if (!InputQuery(Application->Title, pItem->Caption, cLiteral))
return;
pItem->SubItems->Strings[0] = UpperCase(cLiteral.SubString(1, 60));
}
}
//--------------------------------------------------------------------------- |
Me parece que he entendido en al ayuda que poniendo ReadOnly a false en el ListView, de un Item sólo se puede editar el Caption (1ª columna), pero no el resto de SubItems. Lo que busco es que una vez seleccionado un ítem, como Anuales en este caso, al hacer doble click en la fila se abra un cuadro InputQuery para modificar el texto que se ha generado de forma automática pueda ser modificado. Sin embargo, la información que se muestra en el InputQuery es esta:
que corresponde al segundo ítem de la tabla.
Si ejecuto el programa con el depurador y lo paro en pItem = Item;, el valor del Caption es correcto (Anuales), pero al hacer doble click es como si se cambiara. Y esto es lo que me tiene despistado. _________________ Un saludo
Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA) |
|
| Volver arriba |
|
 |
Buildero Master


Registrado: 23 Dic 2003Mensajes: 523Ubicación: Puebla, México
|
Publicado: Vie 04 May, 2007 3:43 pm Asunto: |
|
|
Ahhh ok, ya son más detalles. Pues a simple vista tu código no se ve que genere algún tipo de problema.
Más bien el problema es como bien comentas, algo sucede en el evento del doble click que falla.
Lo que te recomiendo es que pruebes lo siguiente en tu evento doble click:
| Código: | void __fastcall TfGenRec::InfRecDblClick(TObject *Sender)
{
AnsiString cLiteral;
TListItem *Elemento;
if ( InfRec->Selected != NULL )
{
Elemento = InfRec->Selected;
cLiteral = Elemento->SubItems->Strings[0];
if (!InputQuery(Application->Title, Elemento->Caption, cLiteral))
return;
Elemento->SubItems->Strings[0] = UpperCase(cLiteral.SubString(1, 60));
}
} |
Saludos! _________________ Quien hace una pregunta teme parecer un ignorante durante cinco minutos, quien no pregunta se mantiene ignorante toda la vida. |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
Publicado: Jue 10 May, 2007 10:57 am Asunto: |
|
|
Ya encontré el fallo. Resulta que cuando cargo el ListView lo hago con un bucle:
| Código: | while (!Query->Eof)
{
pitem = ListView1->Items->Add();
pItem->Caption = ... etc.
Query->Next();
} |
Claro: Cuando termino de cargar el LsitView, pItem tiene un valor y cuando ejecuto el código en el OnDblClick la variable ya está asignada. Lo que tengo que hacer es añadir en el bucle de carga
de forma que al ejecutarse el evento se seleccione la fila que me interesa. ¡Una tontería como otra cualquiera!  _________________ Un saludo
Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA) |
|
| Volver arriba |
|
 |
Buildero Master


Registrado: 23 Dic 2003Mensajes: 523Ubicación: Puebla, México
|
Publicado: Jue 10 May, 2007 3:47 pm Asunto: |
|
|
Lo dicho....esos pequeños detalles que nos roban el sueño....
Al menos podrás dormir bien el resto de la semana--jejej
Saludos! _________________ Quien hace una pregunta teme parecer un ignorante durante cinco minutos, quien no pregunta se mantiene ignorante toda la vida. |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
|
| Volver arriba |
|
 |
jacko Master


Registrado: 03 Sep 2005Mensajes: 287Ubicación: Colombia
|
Publicado: Dom 22 Jul, 2007 2:36 am Asunto: |
|
|
Hola Angel y Buildero.
Revivo este hilo para comentarles algo extraño. Utilizando el codigo para cargar el ListView:
| Código: | while (!Query->Eof)
{
pItem = ListView1->Items->Add();
pItem->Caption = ... etc.
pItem->SubItem->Add("...etc");
Query->Next();
} |
el cual como pueden ver, no tiene nada raro. Pero lo que me ocurría es que la ultima fila no la mostraba. Por ejemplo, si el Query arroja 5 resultados, pues entra 5 veces al while, pero en el ListView solo se veian 4 filas, que tal?
Esto me tenía loco y desesperado. Revisé en internet, en la ayuda de Builder y nada. Entré al foro y veo que Angel escribe algo de pItem = NULL; , en mi desespero lo copié y pegué a mi codigo y... funcionó!
Por lo cual, el código queda de la siguiente forma:
| Código: | while (!Query->Eof)
{
pItem = ListView1->Items->Add();
pItem->Caption = ... etc.
pItem->SubItem->Add("...etc");
pItem = NULL;
Query->Next();
} |
Lo extraño del asunto es ¿por qué en los códigos de ejemplo no aparece esta bendita instruccion? o ¿éste es un problema aislado que sólo me pasó a mi?
Gracias Angel por evitar mi suicidio!
Saludos!
P.D.: Este apuntador pItem lo borro con delete pItem; ? _________________ Dios es real... a menos que se declare entero! |
|
| Volver arriba |
|
 |
Buildero Master


Registrado: 23 Dic 2003Mensajes: 523Ubicación: Puebla, México
|
Publicado: Dom 22 Jul, 2007 3:08 am Asunto: |
|
|
Que tal jacko
Pues resulta que Angel declara una variable de tipo TListItem de manera global porque asi conviene a sus intereses.
Existen muchas formas de hacer las cosas y esto depende de las técnicas que cada uno de nosotros maneja o al menos las que nos dan mejores resultados.
Te dejo un ejemplo que no deberia de presentar el problema.
| Código: | void __fastcall TForm1::Button1Click(TObject *Sender)
{
try {
//Abrimos el dataset
Query->Open();
//Recorremos el dataset y agregamos los datos al listview
while (!Query->Eof)
{
//Declaramos la variable de tipo TListItem
TListItem *Elemento;
Elemento = ListView1->Items->Add();
Elemento->Caption = "Elemento Numero: " + IntToStr(Elemento->Index);
//Agregamos subitems
Elemento->SubItems->Add("Subelemento1");
Elemento->SubItems->Add("Subelemento2");
//Siguiente registro
Query->Next();
}
} __finally {
//Finalmente cerramos el dataset
Query->Close();
}
} |
Este es un ejemplo sencillo, y la variable se declara dentro del mismo bucle y se destruye al salir del mismo. En el caso del código de Angel el la declara de manera global y necesita asignarle NULL en algún momento para evitar casos extraños como el que se le presentaba.
Saludos! _________________ Quien hace una pregunta teme parecer un ignorante durante cinco minutos, quien no pregunta se mantiene ignorante toda la vida. |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
|
| Volver arriba |
|
 |
jacko Master


Registrado: 03 Sep 2005Mensajes: 287Ubicación: Colombia
|
Publicado: Lun 23 Jul, 2007 5:16 pm Asunto: |
|
|
Angel y Buildero: Todo completamente claro!
Muchas gracias por sus aclaraciones.
Saludos! _________________ Dios es real... a menos que se declare entero! |
|
| Volver arriba |
|
 |
|