Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

ListView: No lo entiendo

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: ListView: No lo entiendo Responder citando


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
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Responder citando

Gracias Buildero. El lunes lo probaré en el trabajo y ya te diré como me fue.
_________________
Un saludo

Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA)
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

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
Código:
pItem = NULL;

de forma que al ejecutarse el evento se seleccione la fila que me interesa. ¡Una tontería como otra cualquiera! Embarassed
_________________
Un saludo

Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA)
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

Lo dicho....esos pequeños detalles que nos roban el sueño.... Shocked

Al menos podrás dormir bien el resto de la semana--jejej Laughing

Saludos!
_________________
Quien hace una pregunta teme parecer un ignorante durante cinco minutos, quien no pregunta se mantiene ignorante toda la vida.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Responder citando

Tienes razón. Gracias por la ayuda.
_________________
Un saludo

Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA)
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

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! Laughing

Saludos!

P.D.: Este apuntador pItem lo borro con delete pItem; ?
_________________
Dios es real... a menos que se declare entero!
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Responder citando

Efectivamente, y la declaración global es porque esa misma variable la uso en varios sitios y así no tengo que andar definiéndola cada dos por tres.
_________________
Un saludo

Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA)
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

Angel y Buildero: Todo completamente claro!

Muchas gracias por sus aclaraciones.

Saludos!
_________________
Dios es real... a menos que se declare entero!
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.