Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi TStringGrid, Sortier-Pfeil anzeigen (https://www.delphipraxis.net/76001-tstringgrid-sortier-pfeil-anzeigen.html)

hoika 28. Aug 2006 15:15


TStringGrid, Sortier-Pfeil anzeigen
 
Hallo #,

ich habe hier ein StringGrid, mit dem ich durch Klick auf die
Überschriftenzeile (FixedRows=1) sortieren kann.
Die Sortieurng klappt auch soweit ganz gut.

Jetzt möchte ich wie beim Explorer einen Sortier-Pfeil darstellen.

Ich habe hier nur einen Code, wie man das mit einem ListView macht,
und leider nichts über StringGrids.


Danke im voraus

Heiko

mkinzler 28. Aug 2006 15:24

Re: TStringGrid, Sortier-Pfeil anzeigen
 
Die Überschriften im Stringgrid sind ja ganz normale Zellen, du mußt also einen eigen Drawroutine( .onDrawCell) implementiere, welche überprüft ob Row 0 ist.

hoika 29. Aug 2006 11:54

Re: TStringGrid, Sortier-Pfeil anzeigen
 
Hallo,

ich habe es mittlerweise hinbekommen.
Da war noch nen c++-builder Bsp,
da konnte ich was entnehmen.

Heiko

Cyberbob 29. Aug 2006 12:24

Re: TStringGrid, Sortier-Pfeil anzeigen
 
Und wie?
Zeig mal bitte deinen Code. Ich musste damals ne andere Komponente verwenden.

hoika 29. Aug 2006 13:14

Re: TStringGrid, Sortier-Pfeil anzeigen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

der Code ist noch nicht so schön strukturiert,
er ist geteilt in einer von TStringGrid abgeleiteten Klasse
und in OnDrawCell des jeweiligen Formulars.

In editgrid.res sind die Pfeile (habe ich aus dem c++-code)

In der StringGrid-Komponente steht
Delphi-Quellcode:
{$R editgrid.res}

dann im Constructor
  PicUp:= TBitmap.Create;
  PicUp.LoadFromResourceName(HInstance, 'ARROWUP');
  PicUp.Transparent:= True;
  PicDown:= TBitmap.Create;
  PicDown.LoadFromResourceName(HInstance, 'ARROWDOWN');
  PicDown.Transparent:= True;
===========

und im OnDrawCell des Forms

Die Zeile
iOrderId=ProjectList.iOrderId

ist True, wenn die aktuell anzuzeigende
Spalte (ACol) die Sortierspalte ist.

ProjectList.bOrderAsc benutze ich zum Umkehrung der Sortierung.

Delphi-Quellcode:

 { center caption }
  if (ARow=0) then
  begin
    iOrderId:= GridColIndex2OrderId(ACol);

    Inc(Rect.Left,2);

    if iOrderId=ProjectList.iOrderId then
    begin
      Rect.Right:= Rect.Right-16;
    end;

    DrawText(c.Handle, PChar(theGrid.Cells[ACol,ARow]),
      Length(theGrid.Cells[ACol,ARow]), Rect,
      DT_END_ELLIPSIS or DT_CENTER);

    if iOrderId=ProjectList.iOrderId then
    begin
      Rect.Right:= Rect.Right+16;
    end;

    if iOrderId=ProjectList.iOrderId then
    begin
      if ProjectList.bOrderAsc then
      begin
        c.Draw(Rect.Right-15,((Rect.Bottom-Rect.Top) div 2)-6,Grid.PicUp);
      end
      else
      begin
        c.Draw(Rect.Right-15,((Rect.Bottom-Rect.Top) div 2)-6,Grid.PicDown);
      end;
    end;

Wie gesagt, ist noch "Beta" ;)
Es läuft, ist aber nicht schön.


Heiko

Real_Thunder 18. Mär 2007 02:40

Re: TStringGrid, Sortier-Pfeil anzeigen
 
Könntest du mir deine OnDrawCell Proceudre etwas genau erklären ????
Ich versuche auch das selbe.......

Ich habe die Procedure folgenermaßen übernommen:

Delphi-Quellcode:
procedure TStartForm.Erg2DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var c:erg2.canvas;


begin
  if (ARow=0) then begin
    iOrderId:= GridColIndex2OrderId(ACol);
    Inc(Rect.Left,2);
    if iOrderId=ProjectList.iOrderId then begin
      Rect.Right:= Rect.Right-16;
    end;
    DrawText(c.Handle, PChar(Erg2.Cells[ACol,ARow]),
      Length(Erg2.Cells[ACol,ARow]), Rect,
      DT_END_ELLIPSIS or DT_CENTER);
    if iOrderId=ProjectList.iOrderId then begin
      Rect.Right:= Rect.Right+16;
    end;
    if iOrderId=ProjectList.iOrderId then
    begin
      if ProjectList.bOrderAsc then begin
        c.Draw(Rect.Right-15,((Rect.Bottom-Rect.Top) div 2)-6,Erg2.PicUp);
      end else begin
        c.Draw(Rect.Right-15,((Rect.Bottom-Rect.Top) div 2)-6,Erg2.PicDown);
      end;
    end;
  end;
end;
Erg2 ist in meinem beispiel das erstellte Stringgrid, bzw das Abgeleitete.... Er zeichnet mir auch die Pfeile in zeile 0, wenn ich :
Delphi-Quellcode:
 c.Draw(Rect.Right-15,((Rect.Bottom-Rect.Top) div 2)-6,Erg2.PicDown);
benutze... ich verstehe das Ganze mit iOrderId:= GridColIndex2OrderId(ACol); nicht..... und wie ich dien mouseclick über der jewaigen zelle abfangen kann....

hoika 19. Mär 2007 07:00

Re: TStringGrid, Sortier-Pfeil anzeigen
 
Hallo,

GridColIndex2OrderId ist eine von mir geschriebene Funktion.
Alle verschiedenen Spalten habe ich selber noch mal durchnumiert.

PersonalId = 0
PersonalName = 1
PersonalVorname = 2

usw.

Ich speichere (an einer anderen Stelle) die Sortierung ab.
Dazu benutze ich diese "OrderId"
du kannst da fürs 1. ach nur Result:= Grid.Col eintragen.

Das Zeichnen des Pfeils übernimmt das EditGrid selber.

Mach mal ein einfaches Bsp., wo du zeigst,
was nicht geht und mail es mal rüber.

Für weitere Erklärungen fehlt mir einfach die Zeit.


Heiko

Real_Thunder 19. Mär 2007 08:57

Re: TStringGrid, Sortier-Pfeil anzeigen
 
Habe es irgendwie letzte Nacht hinbekommen ;)

Nun schetere ich bei dem Versucht mir das Ganze in eine Eigene Komponenten zu Packen...
Ich denk mlal es liegt einfach an meiner Unwissenheit.

Ich habe keinen Plan wie ich das CellDraw und MouseUp in meine Neue Komponenten einbinden soll
bei dem OnCreate macht er mir keine Probleme, das OnCreate habe ich so gemacht:

Delphi-Quellcode:
constructor TSortStringGrid.Create(AOwner:TComponent);
begin
inherited;
  Iorderid:=0;
  PicUp:= TBitmap.Create;
  PicUp.LoadFromResourceName(HInstance, 'ARROWUP');
  PicUp.Transparent:= True;
  PicDown:= TBitmap.Create;
  PicDown.LoadFromResourceName(HInstance, 'ARROWDOWN');
  PicDown.Transparent:= True;
end;

hoika 19. Mär 2007 09:14

Re: TStringGrid, Sortier-Pfeil anzeigen
 
Hallo,

override ist dein Freund.

FCellPropertiesForDrawCell ist eine Event,
welches vom jeweiligen Form wissen will,
wie eine Zelle angezeigt werden soll.

Es entspricht also in etwa dem alten OnDrrawCell.

Das könnte man auch direkt über die Komponente lösen,
indem eine Liste für die Überschrift (z.B. alles zentriert)
und für die einzelnen Spalten/Zeilen geführt wird.
Dabie muss dann aber auch der Zustand "Zelle markiert"
extra mit gespeichert werden (oder die invertierst die Zellenfarbe).

Ich habe das deswegen nicht so weitergemacht,
weil bei einigen meiner Grids noch in Abhängigkeit der Zeile verschiedene Farben
benutzt werden sollten.
Die Spalten-Id alleine reichte halt nicht aus.
Also habe uich das über das per CellPropertiesForDrawCell gemacht.



Heiko


Delphi-Quellcode:

{ cell properties for <TCellPropertiesForDrawCell> }
type
  TCellProperties = record
   { alignment }
    Alignment: TAlignment;

   { column is the sort column }
    bColIsSortCol: Boolean;
   { asc order }
    bAscOrder   : Boolean;

   { font properties }
    Font: record
      Color: TColor;
    end;

   { brush properties }
    Brush: record
      Color: TColor;
    end;
  end; { TCellProperties }


protected
    FCellPropertiesForDrawCell : TCellPropertiesForDrawCell;


     procedure DrawCell(ACol, ARow: Longint; ARect: TRect;
       AState: TGridDrawState); override;


procedure TEditGrid.DrawCell(ACol, ARow: Longint; ARect: TRect;
  AState: TGridDrawState);
begin
  if DefaultDrawing then
    Canvas.TextRect(ARect, ARect.Left+2, ARect.Top+2, Cells[ACol, ARow]);
  inherited DrawCell(ACol, ARow, ARect, AState);


  if Assigned(FCellPropertiesForDrawCell) then
  begin
    FCellProperties.Alignment    := taLeftJustify;
    FCellProperties.Font.Color   := Self.Font.Color;
    FCellProperties.Brush.Color  := Self.Brush.Color;
    FCellProperties.bColIsSortCol := False;
    FCellProperties.bAscOrder    := True;

    if (gdSelected in AState) then
    begin
      FCellProperties.Brush.Color := clActiveCaption;
      FCellProperties.Font.Color := clWhite;
    end
    else
    begin
      FCellProperties.Font.Color := Self.Font.Color;
    end;

    FCellPropertiesForDrawCell(Self,
      ACol, ARow, ARect, AState, FCellProperties);

    InternalDrawCell(ACol, ARow,
      ARect, AState, FCellProperties);
  end;
end;



procedure TEditGrid.InternalDrawCell(ACol, ARow: Longint;
  ARect: TRect; AState: TGridDrawState;
  const theCellProperties: TCellProperties);
var
  c: TCanvas;
begin
  c:= Self.Canvas;

  if ARow<FixedRows then
  begin
    c.Brush.Color:= FixedColor;
  end
  else
  begin
    c.Brush.Color := theCellProperties.Brush.Color;
  end;

  c.Font.Color := theCellProperties.Font.Color;

  c.FillRect(ARect);
  Inc(ARect.Top,2);

  if theCellProperties.Alignment=taCenter then
  begin
    Inc(ARect.Left,2);

    if theCellProperties.bColIsSortCol then
    begin
      ARect.Right:= ARect.Right-16;
    end;

    DrawText(c.Handle, PChar(Cells[ACol,ARow]),
      Length(Cells[ACol,ARow]), ARect,
      DT_END_ELLIPSIS or DT_CENTER or DT_NOPREFIX);

    if theCellProperties.bColIsSortCol then
    begin
      ARect.Right:= ARect.Right+16;
    end;
  end; { if theCellProperties.Alignment=taCenter then }

  if theCellProperties.bColIsSortCol then
  begin
    if theCellProperties.bAscOrder then
    begin
      c.Draw(ARect.Right-15,((ARect.Bottom-ARect.Top) div 2)-6,PicUp);
    end
    else
    begin
      c.Draw(ARect.Right-15,((ARect.Bottom-ARect.Top) div 2)-6,PicDown);
    end;
  end;

 { right alignment }
  if theCellProperties.Alignment=taRightJustify then
  begin
    Dec(ARect.Right,2);

    DrawText(c.Handle, PChar(Cells[ACol,ARow]),
      Length(Cells[ACol,ARow]), ARect,
      DT_END_ELLIPSIS or DT_RIGHT or DT_NOPREFIX);
  end;

 { left alignment }
  if theCellProperties.Alignment=taLeftJustify then
  begin
    Inc(ARect.Left,2);

    DrawText(c.Handle, PChar(Cells[ACol,ARow]),
      Length(Cells[ACol,ARow]), ARect,
      DT_END_ELLIPSIS or DT_NOPREFIX);
  end;
end; { TEditGrid.InternalDrawCell }


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:51 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz