Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

HELP Sorting data in StringGrid

Status
Not open for further replies.

Burtlancaster

Programmer
Jul 22, 2004
12
GB
I have a data currently loaded in to a StringGrid, does anyone know how I can sort this data. For example the Grid has 3 columns (Name, Date, Time) and I need the ability to sort by the 3 columns whilst keep the data appended to its original string.

Thanks for looking.
 
LastCyborg had a solution in thread101-872830. Maybe he can post more info here.

I've seen pascal code to do it but not C++.

James P. Cottingham
[sup]
There's no place like 127.0.0.1.
There's no place like 127.0.0.1.
[/sup]
 
Ok, but as I said this is for TListView Components, I hope it helps.

First:
This is a library so just copy and paste it after that save it with any name (I suggest "ListManager.h").
Code:
#ifndef ListManagerH
#define ListManagerH
//---------------------------------------------------------------------------
template <class T> class ListViewManager : public TComponent
{
protected:
   TLVDeletedEvent     OldOnDelete;
   TLVCompareEvent     OldOnCompare;
   TLVColumnClickEvent OldOnColumnClick;
   int iCurrentSort;
public:
   TListView* lvList;
   __fastcall ListViewManager(TListView* pList);
   TListItem* AddObject(T* pObj);
   void RefreshObject(T* pObj);
   void RefreshItem(TListItem* item);
   void __fastcall OnListViewDeletion(TObject *Sender, TListItem *Item);
   void __fastcall OnListViewColumnClick(TObject *Sender, TListColumn *Column);
   void __fastcall OnListViewCompare(TObject *Sender, TListItem *Item1,
                                    TListItem *Item2, int Data, int &Compare);
};
//---------------------------------------------------------------------------
template <class T>
__fastcall ListViewManager<T>::ListViewManager(TListView* pList)
  : TComponent(pList)
{
   lvList = pList;
   iCurrentSort = -1;
   // Save previous event handlers defined in DFM
   OldOnDelete = lvList->OnDeletion;
   OldOnCompare = lvList->OnCompare;
   OldOnColumnClick = lvList->OnColumnClick;
   // Assign new event handlers
   lvList->OnDeletion    = OnListViewDeletion;
   lvList->OnCompare     = OnListViewCompare;
   lvList->OnColumnClick = OnListViewColumnClick;
}
//---------------------------------------------------------------------------
// This function updates the column text of the specified object
template<class T>
void ListViewManager<T>::RefreshObject(T* pObj)
{
   TListItem* pItem = FindObject(pObj);
   if (pItem)
      RefreshItem(pItem);
}
//---------------------------------------------------------------------------
// Function RefreshItem() updates the columns of text
// and the icon for an object in the listview.
template<class T>
void ListViewManager<T>::RefreshItem(TListItem* item)
{
   if (item)
   {
      T* pObject = (T*)(item->Data);
      if (pObject)
      {
         item->SubItems->Clear();
         for (int i = 0; i < lvList->Columns->Count; i++)
           if (i == 0)
             item->Caption = pObject->GetColumnString(i);
           else
             item->SubItems->Add(pObject->GetColumnString(i));
       }
   }
}
//---------------------------------------------------------------------------
// Function AddItem() adds an object to the listview and
// automatically sets the text of all the columns.
template <class T>
TListItem* ListViewManager<T>::AddObject(T* pObject)
{
   TListItem* item = lvList->Items->Add();
   item->Data = (TObject*)pObject;
   RefreshItem(item);
   return item;
}
//---------------------------------------------------------------------------
// This event ensures that the objects will get deleted
// when the listview is deleted.
template <class T>
void __fastcall ListViewManager<T>::OnListViewDeletion(TObject *Sender, TListItem *Item)
{
   T* pObject = (T*)(Item->Data);
   if (pObject)
   {
      delete pObject;
      Item->Data = NULL;
   }
}
//---------------------------------------------------------------------------
// This event handles automatic sorting.
template <class T>
void __fastcall ListViewManager<T>::OnListViewColumnClick( TObject *Sender,
                                                       TListColumn *Column)
{
   int iColumn = 0;
   for (int i = 0; i < lvList->Columns->Count; i++)
      if (lvList->Columns->Items[i] == Column)
      {
         iColumn = i;
         break;
      }
   lvList->CustomSort(NULL, iColumn);
   if (iCurrentSort == iColumn)
      iCurrentSort = -1;
   else
      iCurrentSort = iColumn;
   if (OldOnColumnClick)
      OldOnColumnClick(Sender, Column);
}
//---------------------------------------------------------------------------
// This event sorts columns by doing a string comparison.
template <class T>
void __fastcall ListViewManager<T>::OnListViewCompare( TObject *Sender,
                                                TListItem *Item1,
                                                TListItem *Item2,
                                                int Data,
                                                int &Compare)
{
   String sValue1;
   String sValue2;
   if (Data == 0)
   {
      sValue1 = Item1->Caption;
      sValue2 = Item2->Caption;
   }
   else
   {
      sValue1 = Item1->SubItems->Strings[Data - 1];
      sValue2 = Item2->SubItems->Strings[Data - 1];
   }
   Compare = sValue1.AnsiCompareIC(sValue2);
   if (iCurrentSort == Data)
   {
      Compare = -Compare;
   }
}
//---------------------------------------------------------------------------
#endif

Second:
Create a class like this:
The class will have as many attributes as elements you want to sort.
This class can be at the .cpp file
Code:
class LastCyborg
{
protected:
   AnsiString sName;
   AnsiString sDate;
   AnsiString sTime;
///   ... etc.

public:
   LastCyborg(AnsiString Name, AnsiString Date, AnsiString Time /*...etc. */);
   AnsiString GetColumnString(int iColumn);
};

LastCyborg::LastCyborg(AnsiString Name, AnsiString Date, AnsiString Time /*...etc. */);
{
   sName = Name;
   sDate = Date;
   sTime = Time;
}
//---------------------------------------------------------------------------
AnsiString LastCyborg::GetColumnString(int iColumn)
{
   switch (iColumn)
   {
      case 0: return sName;
      case 1: return sDate;
      case 2: return sTime;
      //...etc.
   }
   return "";
}
//---------------------------------------------------------------------------

Finally
Using the class
// the next code can be in any event handler
Code:
   ListView1->Clear();
   ListViewManager<LastCyborg> *List = new ListViewManager<LastCyborg>(ListView1);
List->AddObject(new LastCyborg(YourNameValue,YourDateValue,
YourTimeValue));
   delete List;

Doing that, is suppossed that if you press any of the Fixed buttons of the ListView the data will be sorted.

That code is just a piece of a program that I downloaded. so that is not mine I just took that part and I modified, but I hope it help you



--- LastCyborg ---
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top