6 Stimmen

Firemonkey Grid Steuerung - Eine Spalte rechts ausrichten

Ich verwende die FireMonkey-Grid-Steuerung, habe aber ein fortlaufendes Problem beim Versuch, eine Spalte rechts auszurichten. Aus den Beiträgen anderer Benutzer habe ich es geschafft, einen neuen TColumn-Typ zu erstellen, einen Stil darauf anzuwenden (Text als HorzAlign=taTrailing) und theoretisch - gedacht, dass dies die Lösung wäre. Die Werte werden von der OnGetValue-Funktion an die Grid-Steuerung übergeben.

Das Problem ist jedoch, dass obwohl es zuerst gut aussieht, wenn Sie die Leiste/Mausrad etc. scrollen, die neue Spalte vom Typ TColumn nicht korrekt aktualisiert erscheint, wenn die nachstehende Methode/code verwendet wird. Es könnte ein Fehler/eine Eigenschaft des Grids sein (oder die Art und Weise, wie ich es mache). Ich habe .Realign etc... versucht; aber ohne Erfolg. Der einzige Weg, um das Raster wieder in Linie zu bringen, besteht darin, z.B. eine Spaltenänderung vorzunehmen - was dann korrekt neu zeichnet?

Der folgende Code zeigt, dass es sich um ein einfaches TGrid mit 2 Spalten handelt, eine Standard-StringColumn und eine meine neue StringColNum (mit rechter Ausrichtung angewendet). - Jede Hilfe ist willkommen, da dies eine grundlegende Anforderung an jede Gitterarbeit ist.

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Objects, FMX.Grid,
  FMX.Layouts, FMX.Edit;

type
  TForm1 = class(TForm)
    Grid1: TGrid;
    Button1: TButton;
    StyleBook1: TStyleBook;
    procedure Grid1GetValue(Sender: TObject; const Col, Row: Integer;
      var Value: Variant);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TStringColNum = class(TStringColumn)
  private
    function CreateCellControl: TStyledControl; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

constructor TStringColNum.Create(AOwner: TComponent);
begin
  inherited;
end;

function TStringColNum.CreateCellControl: TStyledControl;
var
  t:TEdit;
begin
  Result:=TStringColNum.Create(Self);
  Result.StyleLookup := 'textrightalign';
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Grid1.AddObject(TStringColumn.Create(Self));
  Grid1.AddObject(TStringColNum.Create(Self)); // Rechts ausgerichtete Spalte?

  Grid1.RowCount:=5000;
  Grid1.ShowScrollBars:=True;
end;

procedure TForm1.Grid1GetValue(Sender: TObject; const Col, Row: Integer;
  var Value: Variant);
var
  cell: TStyledControl;
  t: TText;
begin
  if Col=0 then
    Value='Zeile '+IntToStr(Row);

  if Col=1 then
    begin
      cell := Grid1.Columns[Col].CellControlByRow(Row);
      if Assigned(cell) then
        begin
          t := (Cell.FindStyleResource('text') as TText);
          if Assigned(t) then
            t.Text='Zeile '+IntToStr(Row);
        end;
    end;
end;

end.

Mit freundlichen Grüßen. Ian.

5voto

Mike Sutton Punkte 4198

All dies erinnert mich daran, dass ich immer noch meinen Blogbeitrag dazu nicht geschrieben habe.

Wie auch immer, eine Rasterzelle kann jedes Nachfolgerelement von TStyledControl sein (grundlegend jede Steuerelement). Der Standard für eine Textzelle ist TTextCell, was einfach ein TEdit ist. Da es sich um ein TEdit handelt, ist das Ändern der Ausrichtung wirklich einfach: Ändern Sie einfach die TextAlign-Eigenschaft. Es ist nicht notwendig, mit Styles herumzuspielen (es sei denn, Sie möchten wirklich).

Ihre Spalte muss Ihre Zellen in der Methode CreateCellControl erstellen. Sie erstellen eigentlich eine Instanz Ihrer Spalte, was Ihr Hauptproblem ist.

Sie benötigen die Create-Methode für Ihre Spalte nicht (sie macht nichts), also löschen Sie sie (es sei denn, Sie benötigen sie für etwas anderes) und ändern Sie Ihre CreateCellControl.

function TStringColNum.CreateCellControl: TStyledControl;
begin
  Result:=geerbt;
  TTextCell(Result).TextAlign := taTrailing;
end;

Schließlich muss Ihr GetValue-Ereignishandler nichts weiter tun, als den Wert zurückzugeben:

procedure TForm1.Grid1GetValue(Sender: TObject; const Col, Row: Integer;
  var Value: Variant);
begin
  if Col=0 then
    Value='Zeile '+IntToStr(Row);

  if Col=1 then
    Value = 'Zeile '+IntToStr(Row);
end;

1voto

suat dmk Punkte 106

Ich denke, es ist eine Faulheit von Embarcadero.

Das Hinzufügen/Ändern von 3 Zeilen in FMX.Grid.pas löst dieses Problem.

Anstatt das Original FMX.Grid pas zu ändern, empfehle ich, das Original FMX.Grid pas in Ihr Projektverzeichnis zu kopieren, es in Ihr Projekt einzuschließen (im Projekt hinzufügen) und die folgenden Zeilen hinzuzufügen/zu ändern.

TColumn = class(TStyledControl)
  private const
    HorzTextMargin = 2;
    VertTextMargin = 1;
  private
    FReadOnly: Boolean;
    FHorizontalAlign:TTextAlign;//Füge diese Zeile hinzu *********
    FEditMode: Integer;
    FApplyImmediately: boolean;
    ...
    ...
    procedure UpdateCell(ARow: Integer);
  published
    property HorizontalAlign: TTextAlign read FHorizontalAlign write FHorizontalAlign;//füge diese Zeile hinzu *******
    property Align;
    property ClipChildren default False;

procedure TColumn.DefaultDrawCell(const Canvas: TCanvas; const Bounds: TRectF; const Row: Integer;
  const Value: TValue; const State: TGridDrawStates);
var
  R: TRectF;
  Layout: TTextLayout;
  LocalRow: Integer;
begin
  if FDrawable <> nil then
    FDrawable.DrawCell(Canvas, Bounds, Row, Value, State)
  else
...
...
      Layout.Opacity := AbsoluteOpacity;
      (*diese Zeile auskommentieren *****************
      Layout.HorizontalAlign := Grid.TextSettingsControl.ResultingTextSettings.HorzAlign;
      *)
      Layout.HorizontalAlign := HorizontalAlign;//füge diese Zeile hinzu *****

Zuletzt können Sie die neue Eigenschaft in Ihrem Projekt festlegen. z.B:

MeineSpalte.HorizontalAlign:=TTextAlign.taCenter;

0voto

Leslie Kaye Punkte 81

Absteigende Spalten funktionieren nicht gut mit LiveBindings, da der BindManager die Spalten erstellt, sodass Sie mit dem Absteigen herumspielen müssen. Meiner Meinung nach weder elegant noch praktisch.

Alignieren Sie einfach Ihre Zellen im Grid OnPainting Event.

I := Col;
for J := 0 to Grid1.RowCount - 1 do
begin
  T := TTextCell(Grid1.Columns[I].Children[J]);
  T.TextAlign := TTextAlign.taTrailing;
end;

0voto

user3118198 Punkte 1

Wenn Sie LiveBindings verwenden, haben Sie weniger Möglichkeiten, die Spaltenklasse anzupassen, die erstellt wird, aber Sie können Helfer für die Spalte erstellen, die einige Attribute der einzelnen Zellensteuerelemente festlegen. Nicht zu elegant, aber einfach und funktioniert:

unit GridColumnHelper;

interface

uses
  Fmx.Types, Fmx.Controls, Fmx.Grid, Fmx.Edit;

type
  TGridColumnHelper = class helper for TColumn
  public
    procedure SetEditMaxLength(aValue: Integer);
    procedure SetEditTextAlign(aValue: TTextAlign);
  end;

implementation

{ TGridColumnHelper }

procedure TGridColumnHelper.SetEditMaxLength(aValue: Integer);
var
  lControl: TStyledControl;
begin
  for lControl in FCellControls do
  begin
    if lControl is TEdit then
      (lControl as TEdit).MaxLength := aValue;
  end;
end;

procedure TGridColumnHelper.SetEditTextAlign(aValue: TTextAlign);
var
  lControl: TStyledControl;
begin
  for lControl in FCellControls do
  begin
    if lControl is TEdit then
      (lControl as TEdit).TextAlign := aValue;
  end;
end;

end.

Nachdem die Bindung das Raster gefüllt hat, können Sie die Helfer aufrufen:

MyGrid.Columns[0].SetEditTextAlign(TTextAlign.taTrailing);
MyGrid.Columns[1].SetEditMaxLength(15);

0voto

Joe Belladonna Punkte 1309

Lösung von "suat dmk" funktioniert gut, du musst Fmx.Bind.DBLinks.pas und Fmx.Bind.Editors.pas neu kompilieren, wenn du DB-Verknüpfungen verwenden möchtest.

Danach fügst du einfach das in das OnPainting-Ereignis ein:

SGrid1.ColumnByIndex(1).HorizontalAlign := TTextAlign.Leading;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X