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

Registrado: 28 Dic 2002Mensajes: 251Ubicación: Las Rozas - Madrid (España)
|
Publicado: Lun 20 Ene, 2003 12:43 pm Asunto: Ordenar un TListView |
|
|
Hola!
Tengo un TListView (con la propiedad ViewStyle ajustada "vsReport"). Me gustaría saber si alguien tiene un código que permita ordenar cualquiera de sus columnas,de manera tanto ascendente como descendente, cuando el usuario haga click sobre la columna. He visto algunos ejemplos en la ayuda del builder pero no me termino de aclarar.
Gracias. |
|
| Volver arriba |
|
 |
Marky Master

Registrado: 28 Dic 2002Mensajes: 251Ubicación: Las Rozas - Madrid (España)
|
Publicado: Lun 20 Ene, 2003 2:39 pm Asunto: |
|
|
Ya he encontrado la solución (la pongo por si a alguien le interesa). El problema es que si una de las columnas es numérica (por ejemplo: 1,2,3....90,91...) me lo ordena incorrectamente. Por ejemplo, pone: 91, 90, 9, 89, 88... ¿Alguien sabe como arreglar esto?. El código es el siguiente:
Variables globales:
| Código: |
int LastSortedColumn;
bool Ascending;
|
después:
| Código: |
void __fastcall TForm1::FormCreate(TObject *Sender)
{
LastSortedColumn = -1;
Ascending = true;
} |
y finalmente
| Código: |
void __fastcall TForm1::ListView1ColumnClick(TObject *Sender,
TListColumn *Column)
{
if (Column->Index == LastSortedColumn)
Ascending =! Ascending;
else
LastSortedColumn = Column->Index;
static_cast<TListView*>(Sender)->CustomSort(SortByColumn, Column->Index);
} |
donde:
| Código: | int __stdcall SortByColumn(long Item1,long Item2, long Data)
{
int w;
if (Data == 0)
w=AnsiCompareText(((TListItem *)Item1)->Caption, ((TListItem *)Item2)->Caption);
else
w=AnsiCompareText(((TListItem *)Item1)->SubItems->Strings[Data-1],((TListItem *)Item2)->SubItems->Strings[Data-1]);
if (!Ascending)
return -w;
}
|
Como os decía: las columnas numéricas las ordena incorrectamente ¿Alguna idea? |
|
| Volver arriba |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Lun 20 Ene, 2003 7:29 pm Asunto: |
|
|
Hola Marky:
Podrías usar por ejemplo la propiedad 'Tag' de cada columna, por no complicarlo mucho, para indicar el tipo de dato de esa columna. En este caso 0 para texto y 1 para números:
| Código: | int __stdcall SortByColumn(long Item1,long Item2, long Data)
{
TListItem* item1 = reinterpret_cast<TListItem*>(Item1);
TListItem* item2 = reinterpret_cast<TListItem*>(Item2);
bool bCampoNumerico = item1->ListView->Column[Data]->Tag;
int w;
if (Data == 0)
{
w = !bCampoNumerico
? AnsiCompareText(item1->Caption, item2->Caption)
: item1->Caption.ToIntDef(0) - item2->Caption.ToIntDef(0);
}
else
{
w = !bCampoNumerico
? AnsiCompareText(item1->SubItems->Strings[Data-1],
item2->SubItems->Strings[Data-1])
: item1->SubItems->Strings[Data-1].ToIntDef(0)
- item2->SubItems->Strings[Data-1].ToIntDef(0);
}
return Ascending ? w : -w;
} |
Saludos:
_Leo |
|
| Volver arriba |
|
 |
Marky Master

Registrado: 28 Dic 2002Mensajes: 251Ubicación: Las Rozas - Madrid (España)
|
Publicado: Lun 20 Ene, 2003 10:58 pm Asunto: |
|
|
Gracias Leo por tu rapidísima respuesta! Funciona a la perfección.
No había pensado en la propiedad Tag, de hecho es la primera vez que la uso.
Te debo unas cañas y unas bravas  |
|
| Volver arriba |
|
 |
Marky Master

Registrado: 28 Dic 2002Mensajes: 251Ubicación: Las Rozas - Madrid (España)
|
Publicado: Sab 25 Ene, 2003 1:39 am Asunto: |
|
|
Pues no.... ahora hay un pequeño problemilla :__( Si modifico la propiedad "FullDrag" del TListView a "true" y cambio algunas columnas de posición se vuelve a plantear el mismo problema: no ordena correctamente.
¿Porque puede ser esto? |
|
| Volver arriba |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Sab 25 Ene, 2003 8:05 am Asunto: |
|
|
No había previsto ese caso:
Cambiamos la línea:
bool bCampoNumerico = item1->ListView->Column[Data]->Tag;
Por:
TListView* lv = static_cast<TListView*>(item1->ListView);
TListColumn* lc = static_cast<TListColumn*>(lv->Columns->FindItemID(Data));
bool bCampoNumerico = lc->Tag; |
|
| Volver arriba |
|
 |
Marky Master

Registrado: 28 Dic 2002Mensajes: 251Ubicación: Las Rozas - Madrid (España)
|
Publicado: Sab 25 Ene, 2003 11:53 am Asunto: |
|
|
Joder _Leo!!! Eres un auténtico fiera!!! Muchísimas gracias. Ahora si que todo funciona perfectamente :-)
P.D. Si algún día voy para Lanzarote puedes contar con unas cañas de mi cuenta |
|
| Volver arriba |
|
 |
el diego Master


Registrado: 23 Ago 2002Mensajes: 232Ubicación: Paris
|
Publicado: Lun 07 Jul, 2003 3:48 pm Asunto: |
|
|
Hola _Leo,
Intenté utilizar metodo que describen pero no logro compilar ni a palos.
Los dos errores son:
-Imposible de convertir 'int (__stdcall * (_closure )(long,long,long))(long,long,long)' en 'int (__stdcall *)(long,long,long)'
-E2342 Mala correspondencia de tipo en el paramètro 'SortProc' ('int (__stdcall *)(long,long,long)' querido, 'void' obtenido).
Intente castear SortByColumn pero tampoco:
| Código: | ListView->CustomSort((PFNLVCOMPARE)SortByColumn, Column->Index); |
Reproduzco el codigo completo para verificar que no hice ninguna metida de pata:
| Código: | //---------------------------------------------------------------------------
int __stdcall SortByColumn(long Item1, long Item2, long Data)
{
int w;
if (Data == 0)
w = CompareText(((TListItem *)Item1)->Caption, ((TListItem *)Item2)->Caption);
else
w = CompareText(((TListItem *)Item1)->SubItems->Strings[Data-1],((TListItem *)Item2)->SubItems->Strings[Data-1]);
if (Wnd_Doc->Ascending == false)
return -w;
return w;
}
//---------------------------------------------------------------------------
void __fastcall TWnd_Doc::ListViewColumnClick(TObject *Sender, TListColumn *Column)
{
if (Column->Index == LastSortedColumn)
Ascending =! Ascending;
else
LastSortedColumn = Column->Index;
static_cast<TListView*>(Sender)->CustomSort(SortByColumn, Column->Index);
//ListView->CustomSort((PFNLVCOMPARE)SortByColumn, Column->Index);
} | Pereciera que tengo que pasarle los parametros de 'SortByColumn' pero en el ejemplo ustedes no lo hacen y tampoco en los ejemplos de Borland.
Alguna sugerencia? |
|
| Volver arriba |
|
 |
el diego Master


Registrado: 23 Ago 2002Mensajes: 232Ubicación: Paris
|
Publicado: Lun 07 Jul, 2003 4:39 pm Asunto: |
|
|
No dije nada!!!
De puro bruto nomas, habia declarado la funcion "SortByColumn" y no era necesario. |
|
| Volver arriba |
|
 |
jotny Master


Registrado: 17 Feb 2004Mensajes: 226Ubicación: santiago
|
Publicado: Mie 20 Jul, 2005 11:08 am Asunto: hola a todos. |
|
|
Hola a todos.
estoy aprendiendo a ocupar el componente TListView, y ya tengo lo necesario.
traigo de una bd datos y los pongo en esta lista en modo reporte.
pero me gustaria saber como al momento de incorporar contenido a la lista indicarle a la columna que adopte el largo maximo que se vaya insertando?---
porque siempre tengo que alinear a mano las columnas para poder ver los datos que se truncan visualmente para datos muy extensos.
muchisimas gracias.. si aprendo a como hacer eso, entonces ya estaria en condiciones de dar un uso como se debe al componente.
(otra cosa, en el ejemplo anterior,
static_cast<TListView*>(Sender)->CustomSort(SortByColumn, Column->Index);
me manda un error de que SortByColumn no está definido, y tengo la funcion en la clase, la pegué. y que en la funcion SortByColumn existen elementos que tampoco estan definidos.
) ... gracias por la futura ayuda. |
|
| Volver arriba |
|
 |
ifrit Master


Registrado: 12 Jun 2007Mensajes: 509Ubicación: La Habana, Cuba
|
Publicado: Mie 04 Mar, 2009 8:30 pm Asunto: |
|
|
amigos disculpen la ignorancia
pero donde debo poner el codigo paar que funcione?
me imagino que ese tipo de oreden seria dandole clic a x columna no?
si tengo 7 columnas como haria lo mismo? _________________ Todos somos ignorantes, lo que no todos ignoramos lo mismo... |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
Publicado: Mie 06 Jun, 2012 12:47 pm Asunto: |
|
|
Buenas. Recupero este tema porque me está haciendo cosas "raras" este código. Estoy tratando de ordenar esta tabla:
Y si pulso, por ejemplo, la columna etiquetada Refª la primera vez me hace SIEMPRE esta ordenación:
Es decir: La primera vez que pulso me invierte el orden alfabético de la primera columna. La segunda vez ya me lo hace bien, pero no es solución. ¿Alguna idea? _________________ Un saludo
Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA) |
|
| Volver arriba |
|
 |
juanma Cmdr

Registrado: 17 Nov 2005Mensajes: 127Ubicación: Almeria - España
|
Publicado: Jue 07 Jun, 2012 9:18 am Asunto: |
|
|
Hola, a mi el codigo descrito en esta página funciona correctamente. Aunque para mi gusto he modificado el evento ColumnClick para que siempre que pico en una columna diferente, el orden sea ascendente.
| Código: | if (Column->Index == LastSortedColumn)
Ascending =! Ascending;
else {
Ascending = true;
LastSortedColumn = Column->Index;
}
static_cast<TListView>(Sender)->CustomSort(SortByColumn, Column->Index); |
Saludos. |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
Publicado: Jue 29 May, 2014 6:47 pm Asunto: |
|
|
Recupero, una vez más, este tema porque me ha surgido una duda básica.
| _Leo escribió: | | Código: | int __stdcall SortByColumn(long Item1,long Item2, long Data) ... |
|
Acepto collejas múltiples porque la pregunta que voy a hacer es de párvulos desde el punto de vista de C++: ¿Dónde o como defino esa función SortByColum? Sé que lo he hecho otras veces pero no encuentro el código por ningún lado.
Ahora lo tengo así:
| Cita: | En .h
| Código: | public: // User declarations
__fastcall TfBusSoc(TComponent* Owner);
int __stdcall SortByColumn(long Item1,long Item2, long Data);
int LastSortedColumn;
bool Ascending; |
|
| Cita: | En .cpp
| Código: | int __stdcall SortByColumn(long Item1,long Item2, long Data)
{... |
|
Y me está dando estos errores:
E2451 Undefined symbol 'Ascending'
E2034 Cannot convert 'int (__stdcall * (_closure )(long,long,long))(long,long,long)' to 'int (__stdcall *)(long,long,long)'
E2342 Type mismatch in parameter 'SortProc' (wanted 'int (__stdcall *)(long,long,long)', got 'void')
Sé que es una tontería, pero en este momento estoy bloqueado y no soy capaz de ver lo que hago mal.  _________________ Un saludo
Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA) |
|
| Volver arriba |
|
 |
juanma Cmdr

Registrado: 17 Nov 2005Mensajes: 127Ubicación: Almeria - España
|
Publicado: Vie 30 May, 2014 10:30 am Asunto: |
|
|
Hola Angel,
Si lo estás creando como metodo de la clase formulario, has olvidado poner el nombre del fomulario en el cpp.
| Código: | En .cpp
Código:
int __stdcall TFomNN::SortByColumn(long Item1,long Item2, long Data)
{...
|
Saludos,
Juanma |
|
| Volver arriba |
|
 |
|