Einzelnen Beitrag anzeigen

Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#16

AW: FireMonkey ohne LiveBinding?

  Alt 19. Nov 2012, 01:28
Ich habe mal noch etwas herumgespielt und das TMSFMGrid nun von Hand befüllt.

Das Grid habe ich auf einem eigenen Formular, das ich dann zur Laufzeit in das Hauptformular einbette (wie hier beschrieben - dem TRectangle "Body".Parent wird einfach ein Control aus dem Mainform zugewiesen).

Zum Ausblenden einer Spalte setze ich deren Breite einfach auf 0. Benötigt wird sie aber, da darin die ID verwaltet wird.
Das Grid hält dann Kopien der Daten und bei Änderungen werden diese per SQL in die Datenbank geschrieben.
Ändert sich durch eine Editierung die Reihenfolge der Datensätze, wird der Focus auf die aktuelle Zelle automatisch korrigiert.

Das hat so den Vorteil, dass man alle Steuerungen ganz gut kontrollieren kann. Natürlich ist damit etwas mehr Schreibarbeit verbunden.
Extrem große Tabellen sollte man dann nicht vollständig in das Gitter füllen.

Im Moment habe ich mich an die ersten Regelungen heran getastet und halte den Aufwand des Ansatzes für akzeptabel.
Das Grid kann ja Userbasiert sortiert und gruppiert werden. Anhand der ID in der ersten Spalte kann immer eine Verbindung zur Datenbank hergestellt werden.
Selbst Joins lassen sich darstellen und (da das händisch passiert) sinnvoll in die DB zurück speichern.

Löschen und Einfügen von Datensätzen habe ich noch nicht fertig, das wird sich aber lösen lassen.

Schade, dass der Navigator nicht frei (ohne angebundene Datenmange) verwendbar ist.
Eine direkte Bindung an das Gitter habe ich nicht regeln können (wird wohl nicht gehen).


Falls hier mal jemand eine Anregung entnehmen mag:

Delphi-Quellcode:
unit frmPersonsGrid;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Rtti, System.Classes,
  System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs,
  FMX.TMSBaseControl, FMX.TMSGridCell, FMX.TMSGridOptions, FMX.TMSGridData,
  FMX.TMSCustomGrid, FMX.TMSGrid, FMX.Objects, Data.Bind.EngExt,
  FMX.Bind.DBEngExt, FMX.TMSGridDataBinding, System.Bindings.Outputs,
  FMX.Bind.Editors, FMX.Layouts, FMX.Bind.Navigator, Data.Bind.Components,
  Data.Bind.Grid, Data.Bind.DBScope, Data.Bind.Controls;

type
  TFormPersonsGrid = class(TForm)
    TMSFMXGridPersons: TTMSFMXGrid;
    Body: TRectangle;
    BindNavigatorPersons: TBindNavigator;
    Button1: TButton;
    procedure TMSFMXGridPersonsGetCellReadOnly(Sender: TObject; ACol, ARow: Integer; var AReadOnly: Boolean);
    procedure TMSFMXGridPersonsCellCheckBoxClick(Sender: TObject; ACol, ARow: Integer; Cell: TFmxObject);
    procedure TMSFMXGridPersonsCellEditDone(Sender: TObject; ACol, ARow: Integer; CellEditor: TFmxObject);
    procedure TMSFMXGridPersonsGetCellProperties(Sender: TObject; ACol, ARow: Integer; Cell: TFmxObject);
    procedure TMSFMXGridPersonsGetCellData(Sender: TObject; ACol, ARow: Integer; var CellString: string);
  private
    FillFlag: Boolean;
  public
    procedure FillGridData(Id: Integer = 0);
    procedure SaveGridData;
  end;

var
  FormPersonsGrid: TFormPersonsGrid;

implementation

{$R *.fmx}

uses dFlyMagicM, Data.SqlExpr;

{ TFormPersonsGrid }

procedure TFormPersonsGrid.FillGridData(Id: Integer = 0);
var
  DS: TSQLDataSet;
  Grid: TTMSFMXGrid;
  C: Integer;
  R: Integer;
begin
  FillFlag := True;
  DS := DataModuleFlyMagicM.PERSONS;
  Grid := TMSFMXGridPersons;
  DS.Close;
  DS.Open;
  Grid.ColumnCount := 4 + 1;
  Grid.RowCount := DS.RecordCount + 1;
  Grid.ColumnWidths[1] := 0;
  Grid.AddCheckBoxColumn(2);
  for C := 1 to DS.Fields.Count do
  begin
    Grid.Cells[C, 0] := DS.Fields[C - 1].FieldName;
  end;
  for R := 1 to Grid.RowCount do
  begin
    if DS.FieldByName('Id').AsInteger = Id then
      Grid.FocusedCell := Grid.SingleCell(Grid.FocusedCell.Col, R);
    for C := 1 to DS.Fields.Count do
    begin
      Grid.Cells[C, R] := DS.Fields[C - 1].AsString;
    end;
    DS.Next;
  end;
  DS.Close;
  FillFlag := False;
end;

procedure TFormPersonsGrid.SaveGridData;
begin
end;

procedure TFormPersonsGrid.TMSFMXGridPersonsCellCheckBoxClick(Sender: TObject; ACol, ARow: Integer; Cell: TFmxObject);
var
  B: Boolean;
  DS: TSQLDataSet;
  Grid: TTMSFMXGrid;
  Id: Integer;
  FieldName: string;
  Value: string;
begin
  if FillFlag then
    Exit;
  if (ARow > 0) and (ACol = 2) then
  begin
    if Cell is TTMSFMXCheckGridCell then
    begin
      B := (Cell as TTMSFMXCheckGridCell).CheckBox.IsChecked;
      DS := DataModuleFlyMagicM.PersonsUpdate;
      Grid := TMSFMXGridPersons;
      Id := StrToIntDef(Grid.Cells[1, ARow], 0);
      FieldName := Grid.Cells[ACol, 0];
      Grid.FocusedCell := Grid.SingleCell(ACol, ARow);
      if B then
        Value := '1'
      else
        Value := '0';
      DS.Close;
      DS.CommandText := 'UPDATE Persons SET ' + FieldName + ' = :Value WHERE Id = :Id';
      DS.ParamByName('Id').AsInteger := Id;
      DS.ParamByName('Value').AsString := Value;
      DS.ExecSQL();
      DS.Close;
      FillGridData(Id);
    end;
  end;
end;

procedure TFormPersonsGrid.TMSFMXGridPersonsCellEditDone(Sender: TObject; ACol, ARow: Integer; CellEditor: TFmxObject);
var
  DS: TSQLDataSet;
  Grid: TTMSFMXGrid;
  Id: Integer;
  FieldName: string;
  Value: string;
begin
  DS := DataModuleFlyMagicM.PersonsUpdate;
  Grid := TMSFMXGridPersons;
  Id := StrToIntDef(Grid.Cells[1, ARow], 0);
  FieldName := Grid.Cells[ACol, 0];
  Value := Grid.Cells[ACol, ARow];
  DS.Close;
  DS.CommandText := 'UPDATE Persons SET ' + FieldName + ' = :Value WHERE Id = :Id';
  DS.ParamByName('Id').AsInteger := Id;
  DS.ParamByName('Value').AsString := Value;
  DS.ExecSQL();
  DS.Close;
  FillGridData(Id);
end;

procedure TFormPersonsGrid.TMSFMXGridPersonsGetCellData(Sender: TObject; ACol, ARow: Integer; var CellString: string);
var
  C: TFmxObject;
begin
  if (ARow > 0) and (ACol = 2) then
  begin
    C := TMSFMXGridPersons.CellControls[ACol, ARow];
    if C is TTMSFMXCheckGridCell then
      (C as TTMSFMXCheckGridCell).CheckBox.IsChecked := (CellString = '1');
    CellString := '';
  end;
end;

procedure TFormPersonsGrid.TMSFMXGridPersonsGetCellProperties(Sender: TObject; ACol, ARow: Integer; Cell: TFmxObject);
begin
  if Cell is TTMSFMXCheckGridCell then
    (Cell as TTMSFMXCheckGridCell).CheckBox.IsChecked := (TMSFMXGridPersons.Cells[ACol, ARow] = '1');
end;

procedure TFormPersonsGrid.TMSFMXGridPersonsGetCellReadOnly(Sender: TObject; ACol, ARow: Integer; var AReadOnly: Boolean);
begin
  AReadOnly := (ACol in [1, 2]);
end;

end.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (19. Nov 2012 um 09:43 Uhr)
  Mit Zitat antworten Zitat