Link to home
Start Free TrialLog in
Avatar of geocoins-software
geocoins-software

asked on

TDBGrid Title Header Glyphs

I would like to Add the capability of showing a up & down arrow glyph to the column that is currently sorted based on its sort order.

See screenshot for an example from another program i found.

Currently, I change the title caption to bold if its sorted.

See my attached code snipplet

I know how to create glyphs, and I know how to add the glyphs to my current resource file. I just need the code to draw the glyphs on the current sorted columns title header. Because I allow my users to change each columns title header properties (font, background color, ect) - the code should respect the current sorted columns properties.

THanks

procedure TfrmMain.grdMainTitleClick(Column: TColumn);
{$J+}
 const PreviousColumnIndex : integer = -1;
{$J-}
begin
  if grdMain.DataSource.DataSet is TCustomADODataSet then
  with TCustomADODataSet(grdMain.DataSource.DataSet) do
  begin
    try
     grdMain.Columns[PreviousColumnIndex].title.Font.Style := grdMain.Columns[PreviousColumnIndex].title.Font.Style - [fsBold];
    except
    end;
    Column.title.Font.Style := Column.title.Font.Style + [fsBold];
    PreviousColumnIndex := Column.Index;
    if (Pos(Column.Field.FieldName, Sort) = 1)
    and (Pos(' DESC', Sort)= 0) then
     Sort := Column.Field.FieldName + ' DESC'
    else
     Sort := Column.Field.FieldName + ' ASC';
  end;
end;

Open in new window

gsak-screenshot.jpg
Avatar of TheRealLoki
TheRealLoki
Flag of New Zealand image

the standard DBGrid does not allow you to do such abilities
However, you can use a THeaderControl instead
it even goes so far as to allow you to do custom drawing of each header section

here's an example I whipped up for you to do the "sort" icons
you will need :-
a TImageList (callled imagelist1) with 2 images in it
  place a TPanel on the form (called panel1)
  place a THeaderControl (from the Win32 tab) inside panel1
  move your dbgrid into panel1 below the header control

turn off the title in your dbgrid
dbgrid1.Options -> untick "rgTitle"

now use the folliowing code, putting the call to your sort routine in place of "Do_SortDataRoutine"

const
 sort_Reversed = 100;
 
...
  AttachHeaderToDBGrid(HeaderControl1, DBGrid1);
...
 
procedure TForm1.AttachHeaderToDBGrid(header: THeaderControl; grid: TDBGrid);
var
  newsection: THeaderSection;
  i: integer;
begin
  header.Tag := 0;
  header.Sections.Clear;
  if dgindicator in grid.Options then
  begin
    newsection := header.Sections.Add;
    newsection.Text := '';
    newsection.MinWidth := 16;
    newsection.MaxWidth := 16;
    newsection.Width := 16;
    newsection.AllowClick := false;
  end;
  for i := 0 to pred(grid.Columns.Count) do
  begin
    newsection := header.Sections.Add;
    newsection.Text := grid.Columns[i].Title.Caption;
    newsection.Width := grid.Columns[i].Width;
    newsection.AllowClick := true;
  end;
  header.Tag := integer(grid);
end;
 
procedure TForm1.HeaderControl1SectionResize(HeaderControl: THeaderControl; Section: THeaderSection);
var
  dbgridcolid: integer;
begin
  if HeaderControl.Tag = 0 then exit;
  dbgridcolid := Section.ID;
  if (dgindicator in TDBGrid(HeaderControl.Tag).Options) then
    dec(dbgridcolid);
  TDBGrid(HeaderControl.Tag).Columns[dbgridcolid].Field.DisplayWidth := Section.Width;
  TDBGrid(HeaderControl.Tag).Columns[dbgridcolid].Width := Section.Width;
 
end;
 
procedure TForm1.HeaderControl1SectionClick(HeaderControl: THeaderControl; Section: THeaderSection);
var
  dbgridcolid: integer;
  currentsortcol: integer;
  isreversed: boolean;
  i: integer;
begin
  if HeaderControl.Tag = 0 then exit;
  dbgridcolid := Section.ID;
  if (dgindicator in TDBGrid(HeaderControl.Tag).Options) then
    dec(dbgridcolid);
  currentsortcol := TDBGrid(HeaderControl.Tag).Tag;
  isreversed := false;
  if (currentsortcol >= sort_Reversed) then
  begin
    currentsortcol := currentsortcol - sort_Reversed;
    isreversed := true; // will toggle back to normal
  end;
  if (dbgridcolid = currentsortcol) then
  begin
    isreversed := not isreversed; // toggle direction
    if isreversed then
      TDBGrid(HeaderControl.Tag).Tag := dbgridcolid + sort_Reversed
    else
      TDBGrid(HeaderControl.Tag).Tag := dbgridcolid;
  end
  else
  begin
    TDBGrid(HeaderControl.Tag).Tag := dbgridcolid;
    isreversed := false;
  end;
  for i := 0 to pred(HeaderControl.Sections.Count) do
  begin
    if HeaderControl.Sections[i].ID <> Section.ID then
      HeaderControl.Sections[i].ImageIndex := -1
    else if isreversed then
      HeaderControl.Sections[i].ImageIndex := 1 // reversed order
    else
      HeaderControl.Sections[i].ImageIndex := 0; // normal order
  end
// place the call to your sorting here eg.
// Do_SortDataRoutine(dbgridcolid, isreversed);   //( dbgrid column, reversed? )
end;

Open in new window

oh i forgot to mention, set HeaderControl1.Images to ImageList1
ASKER CERTIFIED SOLUTION
Avatar of Mike Littlewood
Mike Littlewood
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of geocoins-software
geocoins-software

ASKER

TheRealLoki:
You can do what i need with a standard TDBGrid.

Mikelittlewood:
Thanks, but i would like to use a TDBGrid
good luck getting an image in the standard grid...
in your other related question you said you wanted to use the grid you already had...
guess you changed your mind :-)