Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1064
  • Last Modified:

Grid/List, Sorting, Component

anyone know a component that
is a "grid" where i can sort on
a click on the "header"
and sort both ways?

it has to be a free component
and it must be "includable" in the
main exe, so there is only the exe
to use.
0
tspse
Asked:
tspse
1 Solution
 
BTechoCommented:
Hello.

There are some choices

http://freespace.virgin.net/giles.lindsay/GJL-Software/ExDBGrid.html

http://www.scalabium.com/faq/smdbgrid.htm ->also checkout FAQ


http://jvcl.sourceforge.net/main.htm ->includes the RXLib DBGrid

Or you can do this yourself using the DBGrid's OnTitleClick event, you can easy sort using SQL with a TQuery. If you use a TTable you can set the IndexName , but note: you must add 2 indexes, one for descending and one for ascending sort , for each field you want to sort both ways.
0
 
kretzschmarCommented:
you can do it with the standard-stringgrid

an older sample

unit stringgridsort_u;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Grids;

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    Button1: TButton;
    CheckBox1: TCheckBox;
    procedure StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Button1Click(Sender: TObject);
    procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
  private
    FSortedColIndex : Integer;
    FSortOrder      : Boolean;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

Var AsIntegerFlag : Boolean;

Function SpecialSort(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result := 0;
  try
    case AsIntegerFlag of
      //AnsiSort
      False : If List[Index1] < List[Index2] then Result := -1
              else If List[Index1] > List[Index2] then Result := 1;
      //IntegerSort
      True  : If StrToInt(List[Index1]) < StrToInt(List[Index2]) then Result := -1
              else If StrToInt(List[Index1]) > StrToInt(List[Index2]) then Result := 1;
    end;
  except
    Result := 0;  //No Sort on Error;
  end;
end;




Procedure SortGrid(AGrid : TStringGrid; ColIndex : Integer; SortOrder : Boolean;
                   //Optional Parameters
                   UseCustomSort : Boolean = False;
                   CustomSortProc : TStringListSortCompare = Nil);
//SortOrder=true->Ascending,SortOrder=False->Descending
//first row is excluded from the sort
var
  SL : TStringList;
  ARow : TStringList;
  I  : Integer;
begin
  if (assigned(AGrid)) and
     (ColIndex > -1) and
     (ColIndex < AGrid.ColCount) then
  begin
     SL := TStringList.Create;
    try
      For I := 1 to AGrid.RowCount - 1 do
      begin
        ARow := TStringList.Create;
        ARow.Assign(AGrid.Rows[i]);
        SL.AddObject(AGrid.Cells[ColIndex,I],ARow);
      end;
      if useCustomSort and assigned(CustomSortProc) then
      try
        SL.CustomSort(CustomSortProc);  //Userdefined sort
      except
        raise;
      end
      else
        SL.Sorted := true; //AnsiCompareString
      Case SortOrder of
        True : For I := 0 to SL.Count - 1 do
                 if Assigned(SL.Objects[I]) then
                   AGrid.Rows[I+1].Assign(TStringList(SL.Objects[I]));
       False : For I := SL.Count - 1  downto 0 do
                 if Assigned(SL.Objects[I]) then
                   AGrid.Rows[AGrid.RowCount - I - 1].Assign(TStringList(SL.Objects[I]));
      end;
    finally
      for I := 0 to sl.count-1 do
        if Assigned(SL.Objects[I]) then
        begin
          TStringList(SL.Objects[I]).Free;
          SL.Objects[I] := Nil;
        end;
      sl.free;
    end;
  end;
end;

Function RandomString(Lngth : Integer; CharSet : TSysCharset) : String;
var C : Char;
begin
  Result := '';
  if (lngth > 0) and not (CharSet = []) then
    while length(Result) < lngth do
    begin
      Repeat
        C := Chr(Random(255));
      Until C in CharSet;
      Result := Result + C;
    end;
end;



procedure TForm1.StringGrid1MouseDown(Sender: TObject;
 Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  ACol,ARow : Integer;
  ASortProc : TStringListSortCompare;
begin
  ASortProc := SpecialSort;
  StringGrid1.MouseToCell(x,y,ACol,ARow);
  AsIntegerFlag := ACol in [1,2];
  if (ARow = 0) and
     (ACol > 0) and
     (Acol < StringGrid1.RowCount) then
    if Button =  mbleft then
    begin
      FSortedColIndex := ACol;
      FSortOrder := True;
      SortGrid(StringGrid1,ACol,True,Checkbox1.Checked,ASortProc)  //asc on columntitle-leftclick
    end
    else
    begin
      FSortedColIndex := ACol;
      FSortOrder := False;
      SortGrid(StringGrid1,ACol,False,Checkbox1.Checked,ASortProc);//Desc on columntitle-rightclick
    end;
end;

//Create a unsorted content
procedure TForm1.Button1Click(Sender: TObject);
var I : Integer;
begin
  StringGrid1.RowCount := 10001;
  StringGrid1.ColCount := 7;
  for i := 1 to 6 do
    StringGrid1.Cells[I,0] := Randomstring(5,['0'..'9','A'..'Z','a'..'z']);
  for i := 1 to 10000 do
  begin
    StringGrid1.Cells[1,I] := IntToStr(I);
    StringGrid1.Cells[2,I] := IntToStr(10001-I);
    StringGrid1.Cells[3,I] := Randomstring(10,['A'..'Z']);
    StringGrid1.Cells[4,I] := Randomstring(10,['0'..'9','A'..'Z','a'..'z']);
    StringGrid1.Cells[5,I] := Randomstring(10,[#0..#255]);
    StringGrid1.Cells[6,I] := '1000';
  end;
end;

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
const CMargin = 5;
begin
  If (ARow = 0) and (ACol = FSortedColIndex) then  //FSortedColIndex->the col, which is sorted
  case FSortOrder of
    true : begin  //Ascending
             StringGrid1.Canvas.Pen.Color := clbtnShadow;
             StringGrid1.Canvas.MoveTo(Rect.Right-CMargin,Rect.Top+CMargin);
             StringGrid1.Canvas.LineTo(Rect.Right-7-CMargin,Rect.Top+CMargin);
             StringGrid1.Canvas.LineTo(Rect.Right-4-CMargin,Rect.Top+7+CMargin);
             StringGrid1.Canvas.Pen.Color := clBtnHighLight;
             StringGrid1.Canvas.LineTo(Rect.Right-CMargin,Rect.Top+CMargin);
           end;
   false : begin  //Descending
             StringGrid1.Canvas.Pen.Color := clBtnHighLight;
             StringGrid1.Canvas.MoveTo(Rect.Right-4-CMargin,Rect.Top+CMargin);
             StringGrid1.Canvas.LineTo(Rect.Right-CMargin,Rect.Top+7+CMargin);
             StringGrid1.Canvas.LineTo(Rect.Right-7-CMargin,Rect.Top+7+CMargin);
             StringGrid1.Canvas.Pen.Color := clbtnShadow;
             StringGrid1.Canvas.LineTo(Rect.Right-4-CMargin,Rect.Top+CMargin);
           end;
  end;
end;

initialization
  Randomize;
end.


meikl ;-)
0
 
soapsiamCommented:
You can use vgLibrary (vgDBGrid), please see following code (my case):-

// Title button onClick event
procedure TfrmMain.DBGrid1TitleBtnClick(Sender: TObject; ACol: Integer;
  Field: TField);
var
    SortString : string;
begin
    SortString := MainDM.ADOSp1.Sort;
    if ShiftDown and (SortString <> '') then
    begin
        if Pos(Field.FieldName, SortString)>0 then
        begin
            if Pos(Field.FieldName+' DESC',SortString) > 0 then
                SortString := StringReplace(SortString, Field.FieldName+' DESC',Field.FieldName+' ASC',[rfIgnoreCase])
            else
                SortString := StringReplace(SortString, Field.FieldName+' ASC',Field.FieldName+' DESC',[rfIgnoreCase]);
        end
        else
            SortString := SortString +', '+Field.FieldName+' ASC';
        MainDM.ADOSp1.Sort := SortString;
        exit;
    end;

    if SortString <> '' then
    begin
        if Pos(Field.FieldName+' ASC',SortString) > 0 then
            SortString := Field.FieldName+' DESC'
        else if Pos(Field.FieldName+' DESC',SortString) > 0 then
            SortString := Field.FieldName+' ASC'
        else
            SortString := Field.FieldName+' ASC';
    end
    else
        SortString := Field.FieldName+' ASC';
    MainDM.ADOSp1.Sort := SortString;
end;

// Drawing title button event
procedure TfrmMain.DBGrid1GetBtnParams(Sender: TObject; Field: TField;
  AFont: TFont; var Background: TColor; var SortMarker: TSortMarker;
  IsDown: Boolean);
var str : string;
begin
    str := MainDM.ADOSp1.Sort;
    if AnsiPos(Field.FieldName+' ASC', str) > 0 then
        SortMarker := smUp
    else if AnsiPos(Field.FieldName+' DESC', str) > 0 then
        SortMarker := smDown
    else
        SortMarker := smNone;
end;

As you can see, you only write code for only 2 events. There are images that already defined in the components.
please come to see it at http://www.vglib.com/link-5.html
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
tspseAuthor Commented:
Ok,

SMDB-Grid: looked ok, but i dit not figure out
how to sort the list after its been filled (didnt have much time, nor did it say in page)

GJL: requires delphi updated to "service pack 2" or what
it is called.

Vg-Lib: costs what i saw.

still not satisfied yet.
0
 
BTechoCommented:
Hi, tspse

I abviously want to sort a DBGrid not a StringGrid. What Database do you use? and what kind of DataSet do you use to access the Database?


For the SMDBGrid.

You can use the OnTitleClick event to catch the Title click.

1. How I can add the sorted column?

SMDBGrid.DataSource.DataSet.DisableControls;

{add a new sorted column in list - ascending order}
with SMDBGrid.SortColumns.Add do
begin
    FieldName := 'yourFieldName';
    SortType := stAscending
end;

{add a new sorted column in list - descending order}
with SMDBGrid.SortColumns.Add do
begin
    FieldName := 'yourFieldName';
    SortType := stDescending;
end;

SMDBGrid.DataSource.DataSet.EnableControls;

--------------------------------------------------------------------------------

2. How I can clear the all sorted columns?

SMDBGrid.DataSource.DataSet.DisableControls;

{clear the all sorted columns}
SMDBGrid.SortColumns.Clear;

SMDBGrid.DataSource.DataSet.EnableControls;

--------------------------------------------------------------------------------

3. How I can change a standard TSMDBGrid glyphs (sorted arrows, indicator symbols etc)?

You can run the Image Editor application (or any other resource workshop), open the SMDBGrid.RES file and change the any glyphs.



Also did you try ExDBGrid?

Description says:
Automatic Column Sorting (Fields that have indexes will be sortable by clicking the Column Titles), QueryByForm and SortByForm implementation (For Paradox and dBASE any column names specified in the SortByForm procedure must already be indexed. For SQL-based tables, the specified columns need not be indexed.)


Also the JVCL DBGrid noted that is had the feature you wanted. So if needed why not apply the Delphi Patch?

0
 
tspseAuthor Commented:
im not using any db because the data comes from a ini-file provided by a third-party site
0
 
tspseAuthor Commented:
BTecho: when i use your code to sort the
SMDBGrid, my program just crashes..

---------------------------
Debugger Exception Notification
---------------------------
Project htht.exe raised exception class EAccessViolation with message 'Access violation at address 004ACB8F in module 'htht.exe'. Read of address 00000030'. Process stopped. Use Step or Run to continue.
---------------------------
OK   Help  
---------------------------
0
 
CleanupPingCommented:
tspse:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
0
 
tspseAuthor Commented:
Hmm, i had totally forgotten about EE :D
The program went down in the drain about the same time
my computer went the same way :D

So basicly i didnt use any code, sort of.
But i still got help, with probably code
that would done the right thing only if i continued,
so i dont dont what to do now, advise would be good on this matter then
(not the code-stuff)

People shouldnt feel that they help out and then not getting any points.
0
 
snehanshuCommented:
Hi!
No comment has been added lately and this question is therefore classified abandoned.

If asker wishes to close the question, then refer to
http://www.experts-exchange.com/help/closing.jsp

Otherwise, I will leave a recommendation in the Cleanup topic area that this question is:

Answered by: kretzschmar

Please leave any comments here within the next seven days. It is assumed that any participant not responding to this request is no longer interested in its final disposition.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

...Snehanshu
EE Cleanup Volunteer

P.S.
  tspse, looks like you didn't try meikl's suggestion at all.
0

Featured Post

[Webinar On Demand] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now