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/)
-   -   TGrid in FM mit Daten füllen (https://www.delphipraxis.net/178633-tgrid-fm-mit-daten-fuellen.html)

Peter-Pascal 18. Jan 2014 20:07

TGrid in FM mit Daten füllen
 
Hallo,

ich suche verzweifelt, wie ich in einem TGrid bei FM die Daten in das Gitter bekomme.

In jedem TGrid müssen einzelne Column (Image,...) zugefügt werden. Jede TImageColumn verfügt über ein bis mehrere TImageCell. Ich finde nichts, wie ich an das TImageCell komme. Da nach Voreinstellung 100 Columm aufgebaut werden, müssen also 100 TImageCell's da sein. Aber wo? Und wie kann ich ein Bild zuweisen?

Vielen Dank.

Gruß Peter

Volker Z. 19. Jan 2014 00:08

AW: TGrid in FM mit Daten füllen
 
Hallo,

Zitat:

ich suche verzweifelt, wie ich in einem TGrid bei FM die Daten in das Gitter bekomme. [...] Aber wo? Und wie kann ich ein Bild zuweisen?
Vielleicht hilft Dir
Delphi-Quellcode:
TGrid.OnGetValue
weiter.

Ein einfaches Beispiel (TGrid und TImage auf das Form klatschen, dem TGrid eine TImageColumn spendieren - erste Spalte - und ins TImage eine beliebige Grafik laden):
Delphi-Quellcode:
procedure TForm1.Grid1GetValue(Sender: TObject; const Col, Row: Integer; var Value: TValue);
begin
  if Col = 0 then
    Value := Image1.Bitmap
end;
Füllt Dir die Zeilen dann mit der der Grafik aus dem TImage

Gruß

Peter-Pascal 19. Jan 2014 14:08

AW: TGrid in FM mit Daten füllen
 
Hallo Volker,

danke für die Antwort. Das funktioniert.

Zur Laufzeit eine Möglichkeit. OnSetValue gibt es auch. Wobei ich nicht verstanden habe, wann die beiden Ereignisse aufgerufen werden und wie ich das Programm gesteuert gestalten soll, wenn sich während der Laufzeit die Inhalte ändern.

Gibt es denn keine Möglichkeit direkt auf TImageCell zuzugreifen? So in der Art ImageCell1.usw.? Wobei ich gerade sehe, dass TImageCell offensichtlich keine Create-Methode in Delphi hat, nur in C++. Was auch immer das bedeutet.

Und ich finde keine Möglichkeit zur Entwicklungszeit, dem Objekt Bilder zuzuweisen. Überall ist das vorhanden, nur hier nicht?

Ich denke, dass FM soweit ganz toll ist, aber bis man es verstanden hat dauert es.

Gruß Peter

Volker Z. 20. Jan 2014 00:32

AW: TGrid in FM mit Daten füllen
 
Hallo,

Zitat:

Wobei ich nicht verstanden habe, wann die beiden Ereignisse aufgerufen werden [...]
GetValue immer dann, wenn sich das Grid (Darstellung des Inhalts irgendwie) ändert. Das heißt, wenn: die Spaltenbreite geändert wird, RowCount geändert wird, das Grid gescrollt wird etc., etc., [...]; kurz: recht häufig.
SetValue immer dann, wenn der Anwender den Zelleninhalt ändert.

Zitat:

[...] und wie ich das Programm gesteuert gestalten soll, wenn sich während der Laufzeit die Inhalte ändern
Vielleicht schaust Du Dir mal das Beispiel hier an. Neben TGrid.UpdateColumns gibt es noch TColumn.UpdateRow (ARow), um gezielt eine Zelle zu aktualisieren - d. h.: GetValue wird für die entsprechende Spalte/Zeile aufgerufen.

Zitat:

Gibt es denn keine Möglichkeit direkt auf TImageCell zuzugreifen? So in der Art ImageCell1.usw.? [...]
AFAIK nein. Du kannst zwar mit:
Delphi-Quellcode:
ImageColumn1.Children [i].Data := Image1.Bitmap
eine Grafik in die entsprechende Zelle quetschen, macht aber nicht viel Sinn (wie oben schon erwähnt sind die Grafikdaten weg, sobald gescrollt wird o. ä.)

Zitat:

Und ich finde keine Möglichkeit zur Entwicklungszeit, dem Objekt Bilder zuzuweisen. Überall ist das vorhanden, nur hier nicht?
Ist so aber auch nicht richtig. Ein VCL TDrawGrid bietet Dir diese Möglichkeit auch nicht.

Vielleicht hilft' s

Gruß

Peter-Pascal 20. Jan 2014 09:49

AW: TGrid in FM mit Daten füllen
 
Hallo Volker,

so ein Beispiel habe ich gesucht, wie Du es gezeigt hast. Warum ich es nicht gefunden habe, weiß ich nicht. Jetzt wird einiges klarer (insbesondere mit Deinen Erläuterungen) und mit UpdateColumn kann es zur Laufzeit gesteuert werden.

Weiß Du jetzt noch, wie ich FixedSpalten hinbekomme?

Danke und viele Grüße
Peter

Volker Z. 21. Jan 2014 00:22

AW: TGrid in FM mit Daten füllen
 
Hallo,

Zitat:

Weiß Du jetzt noch, wie ich FixedSpalten hinbekomme?
Was genau meinst Du den damit?
  • Spalten mit fixer (nicht veränderbarer Breite)
  • Eine FixedCol, die Ähnlichkeit mit der Headerzeile hat
  • Eine FixedCol à la (VCL) TStringGrid, die am linken Controlrand "stehen bleibt" beim horizontalen Scrollen
  • Etwas völlig anderes

Gruß

Peter-Pascal 21. Jan 2014 10:10

AW: TGrid in FM mit Daten füllen
 
Sorry, da habe ich mich nicht präzise genug ausgedrückt.

Eine Spalte, die am linken Rand stehen bleibt, wenn das Gitter gescrollt wird.

Volker Z. 21. Jan 2014 16:42

AW: TGrid in FM mit Daten füllen
 
Hallo,

Zitat:

Eine Spalte, die am linken Rand stehen bleibt, wenn das Gitter gescrollt wird.
Habe ich befürchtet. Eine einfach Möglichkeit (Property entsprechend setzen o. ä.), um die erste(n) Spalten fixed zu bekommen habe ich noch nicht gefunden (auch noch nicht intensiv danach gesucht).

Ich kenne Deine Problemstellung nicht; wenn es sich eher um eine Standarddarstellung (kein rotierendes Grid o. ä.) handelt, dann könntest Du die fixe Spalte(n) doch mit einem zweiten Grid erschlagen, das entsprechend über dem anderen Grid liegt.

Dann muss Du nur noch das Selektieren bzw. Scrollen synchronisieren und die Höhe des "fixen" Grids anpassen, wenn der horizontale Scrollbalken ein bzw. ausgeblendet wird.

Das ganze könntest Du so machen (nur mal kurz skizziert):
  • 2x TGrid aufs Form
  • Grid1: die erste Spalte ein TColumn, gefolgt von den Spalten, die Du zur Darstellung Deines Inhalts benötigst
  • Grid2: keine Spalten
Delphi-Quellcode:
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Rtti, System.Classes,
  System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs,
  FMX.StdCtrls, FMX.Grid, FMX.Layouts, FMX.Header;

type
  THeaderCell = class (FMX.Header.THeader)
  private
    procedure  InternalResize (Sender : TObject);
  protected
    procedure  SetData (const Value: TValue); override;
  public
    constructor Create (Owner : TComponent); override;
  end;

  THeaderColumn = class (FMX.Grid.TColumn)
  protected
    function CreateCellControl : TStyledControl; override;
  end;

  // Für den Zugriff auf die Scrollbars
  TGrid = class (FMX.Grid.TGrid)
  end;

  TForm1 = class(TForm)
    Grid1: TGrid;
    Column1: TColumn;
    ImageColumn1: TImageColumn;
    StringColumn1: TStringColumn;
    Grid2: TGrid;
    StyleBook1: TStyleBook;
    procedure FormCreate(Sender: TObject);
    procedure Grid1Paint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
    procedure Grid1SelChanged(Sender: TObject);
    procedure Grid2SelChanged(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure SyncVScrollBarValue (Sender : TObject);
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure THeaderCell.InternalResize (Sender : TObject);
begin
  Items [0].Width := Width + 1
end;

procedure THeaderCell.SetData (const Value : TValue);
begin
  Items [0].Text := Value.AsString
end;

constructor THeaderCell.Create (Owner : TComponent);
var
  i : THeaderItem;
begin
  inherited Create (Owner);

  i := THeaderItem.Create (Self);
  i.Enabled := False;
  AddObject (i);

  OnResize := InternalResize
end;

function THeaderColumn.CreateCellControl : TStyledControl;
begin
  Result := THeaderCell.Create (Self)
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Grid1.OnVScrollChange := SyncVScrollBarValue;

  Grid2.AddObject (THeaderColumn.Create (Self));
  Grid2.Position.X := Grid1.Position.X;
  Grid2.Position.Y := Grid1.Position.Y;

  Column1.Enabled := False;
  Column1.Width  := Grid2.Width - 5
end;

procedure TForm1.Grid1Paint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF);
begin
  if Grid1.HScrollBar.Visible then
    Grid2.Height := Grid1.Height - Grid1.HScrollBar.Height - 2
  else
    Grid2.Height := Grid1.Height
end;

procedure TForm1.Grid1SelChanged(Sender: TObject);
begin
  Grid2.Selected := Grid1.Selected
end;

procedure TForm1.Grid2SelChanged(Sender: TObject);
begin
  Grid1.Selected := Grid2.Selected
end;

procedure TForm1.SyncVScrollBarValue(Sender: TObject);
begin
  Grid2.VScrollBar.Value := Grid1.VScrollBar.Value
end;

end.
Sicherlich nicht der Weisheit letzter Schluss (soll auch nur grob den Weg skizzieren). Letztlich wäre da eine eigene Klasse zu bauen (ich habe mir aber die FMX Klassen noch nicht so genau angesehen).

Vielleicht hilft 's weiter oder ein Kollege hat 'ne bessere Idee.

Gruß

Peter-Pascal 21. Jan 2014 21:58

AW: TGrid in FM mit Daten füllen
 
Hallo Volker,

doch, doch, das hilft gewaltig weiter. Ganz besonders, was Du über das Synchronisieren der Scrollbalken geschrieben hast. Ich suche auch nach einer Möglichkeit die Scrollbalken insbesondere bei TListBox zu synchronisieren. Ich hoffe das klappt da auch.

Das werde ich beides mal ausprobieren.

Vielen Dank für Deine Mühe

Gruß Peter

Volker Z. 22. Jan 2014 00:23

AW: TGrid in FM mit Daten füllen
 
Hallo,

Zitat:

doch, doch, das hilft gewaltig weiter. Ganz besonders, was Du über das Synchronisieren der Scrollbalken geschrieben hast.
Freut mich.

Zitat:

Ich suche auch nach einer Möglichkeit die Scrollbalken insbesondere bei TListBox zu synchronisieren. Ich hoffe das klappt da auch.
Ja, das sollte schon klappen (
Delphi-Quellcode:
TListBox = class (FMX.ListBox.TListBox)end;
vor der Deklaration des Forms).

Ich habe nur noch nicht verstanden, warum man bei Emba wohl glaubt die Scrollbars unbedingt vor den Programmieren verstecken zu müssen (ich beiß da doch kein Stück aus den Dingern raus), oder ich habe einfach den tieferen Sinn dahinter noch nicht kapiert - aber vielleicht erhellt mich mal wer.

Gruß

Peter-Pascal 22. Jan 2014 19:42

AW: TGrid in FM mit Daten füllen
 
Hallo Volker,

Dein Listing funktioniert perfekt auch bei TListbox. Mit der Maus. Aber merkwürdigerweise nicht mit dem Finger. Ich versteh das nicht, bewege ich die Scrollbalken per Maus, bewegt sich die angeschlossenen Listbox im Gleichschritt.

Aber per Touch nicht.

Ich habe versucht das Ereignis zu finden. OnGesture offenbar nicht. Delphi unterscheidet zwischen Standardgesten und interaktiven Gesten. OnGesture wird nur bei interaktiven Gesten ausgeführt, soweit ich das begriffen habe.

Weißt Du welches Ereignis ausgelöst wird, wenn die ListBox per Touch gescrollt wird? Dann kann ich vielleicht dort auch die andere ListBox synchronisieren?

Danke nochmal für Deine Hilfe.

Hat man ein Problem gelöst öffnet sich das nächste. So langsam bin ich etwas enttäuscht von FM.

Mit den ListBox wollte ich einen Zeitstrahl aufbauen. Jedes Ereignis ein Listboxitem, welches abhängig von der Zeit seine Größe zugewiesen bekommt.

Ich schreibe das unter Win 8.1 mit Metropolis UI. Mir gefällt die Oberfläche und ich finde das Design sehr edel. Zumal ich einen Touch-Screen Monitor habe. Aber leider bin ich bislang nur auf Probleme gestoßen.

Gruß Peter

Volker Z. 22. Jan 2014 22:21

AW: TGrid in FM mit Daten füllen
 
Hallo,

Zitat:

[...] funktioniert [...] Mit der Maus [...] Aber per Touch nicht
Wie habe ich mir das vorzustellen? Du ziehst mit dem Finger den Scrollbalken nach unten/oben: die Liste scrollt, der Balken ändert seine Position aber die zweite Liste ändert ihre Position nicht. Oder machst Du etwas anderes? Stichwort: Gesten.

Ich kann es leider nicht nachbilden und testen - Grund: fehlendes Finger-Fummel-Gerät.

Gruß

Volker Z. 22. Jan 2014 23:33

AW: TGrid in FM mit Daten füllen
 
Hallo,

ich sehe gerade, dass die TScrollBox zwar das MouseWheel verarbeitet und die Position des vertikalen Scrollbars neu setzt, aber kein OnVScrollChange getriggert wird :wall:.

Mit:
Delphi-Quellcode:
procedure TForm1.ListBox1MouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean);
begin
  ListBox2.VScrollBar.Value := ListBox1.VScrollBar.Value - ListBox1.VScrollBar.SmallChange * WheelDelta / 120
end;
solltest Du das synchronisiert bekommen. Vielleicht ergibt sich dabei auch etwas in Sachen Touchproblem.

Gruß

Peter-Pascal 23. Jan 2014 10:09

AW: TGrid in FM mit Daten füllen
 
Hallo Volker,

nochmals vielen Dank, dass Du Dich meinen Problemen so annimmst. Dabei hilfst Du mir FM besser zu verstehen. Wobei ich sagen muss, dass mir vieles nicht so ganz einleuchtet.

Nun denn: mit den Fingern mache ich in der Tat etwas anderes. Ich bewege nicht den Scrollbalken, sondern direkt mit einem Finger mitten auf die Liste und bewege so die Liste selber. Wenn ich den Scrollbalken mit den Fingern bewege, funktioniert die Synchronisation mit dem anderen Scrollbalken.

Mit den Fingern direkt auf der Liste verschiebe ich in die andere Richtung als ich den Scrollbalken mit der Maus verschiebe. Wenn ich die Liste nach rechts scrollen will, verschiebe ich den Slider vom Scrollbalken auch nach rechts. Mit dem Finger bewege ich die ganze Liste nach links. Ich hoffe ich habe mich einigermaßen verständlich ausgedrückt.

So weit so gut. Aber wie auch immer es wird auch der Scrollbalken bewegt. Ich verstehe nicht, warum dann die Synchronisation nicht funktioniert. Offensichtlich wird OnHScrollChange nicht aufgerufen.

Wo hast Du gefunden, wie die einzelnen Methoden getriggert sind?

Gruß Peter

Volker Z. 23. Jan 2014 15:36

AW: TGrid in FM mit Daten füllen
 
Hallo,

Zitat:

[...] Dabei hilfst Du mir FM besser zu verstehen. Wobei ich sagen muss, dass mir vieles nicht so ganz einleuchtet.
Ich muss gestehen, dass ich bisher noch nicht wirklich mit FM gearbeitet habe. Ist für mich eine gute Gelegenheit mich da mal ein bisschen einzuarbeiten :wink:.

Zitat:

Nun denn: mit den Fingern mache ich in der Tat etwas anderes [...]
Habe ich mir fast gedacht. Wie schon gesagt: Das mit dem Wischen, Tippen und Finger-Fummeln kann ich nicht testen. Aber mit dem Ansatz Gesten solltest Du schon richtig liegen.

Zitat:

[...] Delphi unterscheidet zwischen Standardgesten und interaktiven Gesten. OnGesture wird nur bei interaktiven Gesten ausgeführt, soweit ich das begriffen habe.
Nö. Die Standardgesten werden schon getriggert, wenn Du einen GestureManager nutzt, den jeweiligen Komponenten zuweist und die entsprechenden Standardgesten (im OI: Touch -> Gestures -> Standard) einhängst.

Ich kann es zwar nicht mit Wischen, aber ich habe mal versucht das mit der Maus nachzubilden:
  • Aufs Form eine ScrollBox (ScrollBox1), in diese Scrollbox ein Panel gelegt.
  • Das Panel: Position (0, 0), Höhe und Breite so eingestellt, dass es die Grenzen der Scrollbox (deutlich) überschreitet.
  • Dieses Konstrukt kopiert und aufs Form geklatscht.
  • Ein GestureManager auf Form und an die ScrollBox1 gehängt (OI Eigenschaft Touch.GestureManager), als Standardgesten [Left,Right,Up,Down] und der ScrollBox1 ein OnGesture spendieren.
Dann kann ich mit:
Delphi-Quellcode:
type
  TScrollBox = class (FMX.Layouts.TScrollBox)

  end;
 
  TForm1 = class(TForm)
    ScrollBox1 : TScrollBox;
    Panel1: TPanel;
    GestureManager1: TGestureManager;
    ScrollBox2: TScrollBox;
    Panel2: TPanel;
    procedure ScrollBox1Gesture(Sender: TObject; const EventInfo: TGestureEventInfo; var Handled: Boolean);
    procedure FormCreate(Sender: TObject);
  private
    procedure SyncHScrollBars (Sender : TObject);
    procedure SyncVScrollBars (Sender : TObject);
  end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ScrollBox1.OnHScrollChange := SyncHScrollBars;
  ScrollBox1.OnVScrollChange := SyncVScrollBars
end;

procedure TForm1.ScrollBox1Gesture(Sender: TObject; const EventInfo: TGestureEventInfo; var Handled: Boolean);
begin
  case EventInfo.GestureID of
    sgiDown : ScrollBox1.ScrollTo (0, -40);
    sgiLeft : ScrollBox1.ScrollTo (-40, 0);
    sgiRight : ScrollBox1.ScrollTo (40, 0);
    sgiUp   : ScrollBox1.ScrollTo (0, 40);
  end
end;

procedure TForm1.SyncHScrollBars (Sender : TObject);
begin
  ScrollBox2.HScrollBar.Value := ScrollBox1.HScrollBar.Value
end;

procedure TForm1.SyncVScrollBars (Sender : TObject);
begin
  ScrollBox2.VScrollBar.Value := ScrollBox1.VScrollBar.Value
end;
das Wischverhalten nachbilden und die beiden Scrollboxen synchronisieren.

Vielleicht hilft Dir das Beispiel Deine Listboxen (die sind ja letztlich von TScrollBox abgeleitet) zu synchronisieren.

Zitat:

Wo hast Du gefunden, wie die einzelnen Methoden getriggert sind?
FMX Sourcen anschauen.

Gruß

Peter-Pascal 23. Jan 2014 21:34

AW: TGrid in FM mit Daten füllen
 
Heureka,

das funktioniert soweit bei FMX mit HD. Und dann sieht es auch ganz gut aus.

Vielen Dank.

Ich bin jetzt auch angefangen, mir die Sourcen anzuschauen. Ich glaube dadurch bekomme ich dann doch vielleicht mehr Verständnis von FMX. Ob es die richtige Entscheidung ist Metropolis UI zu verwenden, weiß ich nicht. Bislang hat mich allein nur herauszufinden, welche Komponente für die Darstellung einer Zeitleiste in Betracht kommt, ein paar Wochenenden gekostet.

Leider ist das bei Metropolis offenbar alles anders. Die Standardgesten funktionieren in Metropolis nicht. In FMX bekomme ich das alles sauber hin.

Gruß Peter

Volker Z. 24. Jan 2014 00:31

AW: TGrid in FM mit Daten füllen
 
Hallo,

Zitat:

Leider ist das bei Metropolis offenbar alles anders. Die Standardgesten funktionieren in Metropolis nicht. In FMX bekomme ich das alles sauber hin.
Was hakt denn da genau? Ich habe das Beispiel aus Post #15 als FireMokey-Anwendung für Metropolis-UI Delphi (Leere Metropolis-UI-Anwendung) erstellt. Machst Du noch was im FormGesture?

Gruß

Peter-Pascal 24. Jan 2014 10:29

AW: TGrid in FM mit Daten füllen
 
Es ist mir peinlich, aber bei mir funktioniert es in Metropolis FMX nicht. Unter "Normal-" FMX schon.

Delphi-Quellcode:
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Ani, FMX.Layouts, FMX.Gestures,
  FMX.StdCtrls;

type

 TScrollBox = class (FMX.Layouts.TScrollBox)

   end;

  TForm1 = class(TForm)
    StyleBook1: TStyleBook;
    ToolbarHolder: TLayout;
    ToolbarPopup: TPopup;
    ToolbarPopupAnimation: TFloatAnimation;
    ToolBar1: TToolBar;
    ToolbarApplyButton: TButton;
    ToolbarCloseButton: TButton;
    ToolbarAddButton: TButton;
    ScrollBox1: TScrollBox;
    Panel1: TPanel;
    GestureManager1: TGestureManager;
    procedure ToolbarCloseButtonClick(Sender: TObject);
    procedure FormGesture(Sender: TObject;
      const EventInfo: TGestureEventInfo; var Handled: Boolean);
    procedure FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char;
      Shift: TShiftState);
    procedure ScrollBox1Gesture(Sender: TObject;
      const EventInfo: TGestureEventInfo; var Handled: Boolean);
  private
    FGestureOrigin: TPointF;
    FGestureInProgress: Boolean;
    { Private-Deklarationen }
    procedure ShowToolbar(AShow: Boolean);
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  var KeyChar: Char; Shift: TShiftState);
begin
  if Key = vkEscape then
    ShowToolbar(not ToolbarPopup.IsOpen);
end;

procedure TForm1.ToolbarCloseButtonClick(Sender: TObject);
begin
  Application.Terminate;
end;

procedure TForm1.FormGesture(Sender: TObject;
  const EventInfo: TGestureEventInfo; var Handled: Boolean);
var
  DX, DY : Single;
begin
showmessage('Hello World');
  if EventInfo.GestureID = igiPan then
  begin
    if (TInteractiveGestureFlag.gfBegin in EventInfo.Flags)
      and ((Sender = ToolbarPopup)
        or (EventInfo.Location.Y > (ClientHeight - 70))) then
    begin
      FGestureOrigin := EventInfo.Location;
      FGestureInProgress := True;
    end;

    if FGestureInProgress and (TInteractiveGestureFlag.gfEnd in EventInfo.Flags) then
    begin
      FGestureInProgress := False;
      DX := EventInfo.Location.X - FGestureOrigin.X;
      DY := EventInfo.Location.Y - FGestureOrigin.Y;
      if (Abs(DY) > Abs(DX)) then
        ShowToolbar(DY < 0);
    end;
  end
end;

procedure TForm1.ScrollBox1Gesture(Sender: TObject;
  const EventInfo: TGestureEventInfo; var Handled: Boolean);
begin
showmessage('Hello World');
case EventInfo.GestureID of
     sgiDown : ScrollBox1.ScrollTo (0, -40);
     sgiLeft : ScrollBox1.ScrollTo (-40, 0);
     sgiRight : ScrollBox1.ScrollTo (40, 0);
     sgiUp : ScrollBox1.ScrollTo (0, 40);
   end;
end;

procedure TForm1.ShowToolbar(AShow: Boolean);
begin
  ToolbarPopup.Width := ClientWidth;
  ToolbarPopup.PlacementRectangle.Rect := TRectF.Create(0, ClientHeight-ToolbarPopup.Height, ClientWidth-1, ClientHeight-1);
  ToolbarPopupAnimation.StartValue := ToolbarPopup.Height;
  ToolbarPopupAnimation.StopValue := 0;

  ToolbarPopup.IsOpen := AShow;
end;

end.
Ich habe eine neue Anwendung erstellt: Firemonkey-Anwendung für Metropolis UI Delphi - anschließend Leere Metropolis-UI Anwendung.
Den Gesturemanager habe ich bei der Scrollbox eingehakt.

Gruß

Volker Z. 24. Jan 2014 14:30

AW: TGrid in FM mit Daten füllen
 
Hallo,

Zitat:

Es ist mir peinlich, aber bei mir funktioniert es in Metropolis FMX nicht. Unter "Normal-" FMX schon.
Peinlich muss da gar nix sein. Sieht so aus, als ob es ein paar nette kleine Unterschiede zwischen Metropolis UI und FM Desktop Anwendungen gibt.

Ich konnte Dein Problem mal nachstellen (vermute ich mal). Wenn die Metropolis UI Anwendung mit der Eigenschaft
Delphi-Quellcode:
FullScreen := True
(Standardeinstellung, hatte ich geändert :oops:) läuft, dann werden die Gesten offenbar nicht getriggert.

Abhilfe schafft
Delphi-Quellcode:
BorderStyle := bsNone
. Wo der Unterschied genau liegt und was es für Auswirkungen hat muss ich erst noch untersuchen.

Gruß

Peter-Pascal 24. Jan 2014 14:57

AW: TGrid in FM mit Daten füllen
 
Es ist unfassbar. Ich habe nur Fullscreen auf false gesetzt und die Routine onGesture von der Scrollbox wird ausgeführt.

So langsam muss ich aber mal Dir gegenüber meine Bewunderung zum Ausdruck bringen. Ich habe gestern bis fast Mitternacht an diesem Problem gerätselt und Du hast es in recht kurzer Zeit gefunden. Respekt!

Beste Grüße
Peter

Volker Z. 24. Jan 2014 15:12

AW: TGrid in FM mit Daten füllen
 
Hallo,

Zitat:

[...] Ich habe gestern bis fast Mitternacht an diesem Problem gerätselt und Du hast es in recht kurzer Zeit gefunden.
Wenn Kollege Zufall behilflich ist.

Hast Du es mit
Delphi-Quellcode:
FullScreen := True
und
Delphi-Quellcode:
BorderStyle := bsNone
schon versucht?

Gruß

Peter-Pascal 24. Jan 2014 15:15

AW: TGrid in FM mit Daten füllen
 
Ich habe mir auch die Seite "Gestenunterstützung in Metropolis-UI-Anwendungen" in der Hilfe angeschaut. Bringt mich aber nicht viel weiter. Erklärt, dass es wegen Windows 8 einen Unterschied zu Windows 7 gibt. Und man kann eine globale Variable setzten. Das habe ich getan, aber trotzdem keine Änderung. Wobei ich nicht weiß, was mit "Hauptprogrammdatei" gemeint ist.

Ich habe Fullscreen auf False. Nur so funktioniert es, dass onGesture aus Scrollbox1 antwortet. Borderstyle ist egal, so wie ich das jetzt gesehen habe

Volker Z. 24. Jan 2014 21:26

AW: TGrid in FM mit Daten füllen
 
Hallo,

Zitat:

[...] Wobei ich nicht weiß, was mit "Hauptprogrammdatei" gemeint ist.
Die .dpr Deines Projekts.

Zitat:

Ich habe Fullscreen auf False. Nur so funktioniert es, dass onGesture aus Scrollbox1 antwortet. Borderstyle ist egal, so wie ich das jetzt gesehen habe
Wenn das Ändern der Eigenschaft BorderStyle keine Auswirkung zeigt, dann macht wohl XE4 ≠ XE5 und/oder Windows 8 ≠ Windows 8.1 den Unterschied aus. Der BorderStyle wird während des Erstellens des Hauptformulars so oder so von bsSizeable auf bsNone geändert.

Gruß

Peter-Pascal 26. Jan 2014 15:08

AW: TGrid in FM mit Daten füllen
 
Hallo Volker,

möglich, dass es wegen der Versionsunterschiede zu den Ergebnissen führt. Macht nichts, dann muss ich eben umdenken. Bin schließlich noch am Anfang.

Vielleicht sollte ich mal schreiben, was ich überhaupt plane: Eine Zeitleiste in der Ereignisse der Geschichte aufgenommen werden und mit Klick nähere Details dargestellt werden.
Also fast so wie die Bespiele von Metropolis UI. Das hat mir gut gefallen. Die Listbox erschien mir auf den ersten Blick dazu sehr geeignet mit dem MetropolisItem. Das Item kann Text und ein Bild aufnehmen. Die ListBox auf Horizontal gestellt, wirkte perfekt. Aber im Detail kamen die Probleme. Zum Beispiel: ES ist möglich mehrere Columns für die Listbox einzustellen, aber die werden nicht über den Bildschirmrand hinaus dargestellt, sondern die Items werden immer kleiner gerechnet.

Egal ich probiere noch weiter.

Eine Frage habe ich noch. Warum muss am Anfang TListBox = class (FMX.Listbox.TListbox); end; hinzugefügt werden? Wobei FMX.Listbox.pas der Name der Unit ist? Klar damit der Zugriff auf TScrollbox vorhanden, aber wieso weiß Delphi das nicht ohne diesen Aufruf?

Aber wie dem auch sei, Du hast mir sehr geholfen. Vielen Dank dafür.

Gruß Peter

Volker Z. 26. Jan 2014 22:01

AW: TGrid in FM mit Daten füllen
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo,

Zitat:

Vielleicht sollte ich mal schreiben, was ich überhaupt plane: Eine Zeitleiste in der Ereignisse der Geschichte aufgenommen werden und mit Klick nähere Details dargestellt werden [...]
Mit einer Listbox - hm? Ich weiß zwar nicht was Du genau vorhast, für mich wäre eine Listbox wohl nicht die erste Wahl. Ich denke, Dein Vorhaben ließe sich doch recht einfach Darstellen (siehe Grafiken im Anhang):
  • Eine Klasse, die die Eckdaten der Ereignisse halten
  • Eine Liste (z. B. TObjectList), die die Ereignisse enthält
  • Eine TScrollBox aufs Formular
  • In der ScrollBox eine TLine (Line1.Position.X := 0) mit einer Breite, die der Zeitspanne entspricht
  • Für die "Einträge" zur Laufzeit z. B. ein TCalloutRectangle mit einer TText Komponente (und ein TImage) drauf erzeugen und alles entsprechend positionieren
  • Einen "fixen" OnClick Handler den TCalloutRectangle und TText Komponenten einhängen (der sucht dann den entsprechenden Eintrag in der Listen und zeigt die zugehörigen Details an)
Wenn das für Dich eine Option ist, dann solltest Du Dir dafür besser eigene Klassen ableiten.

Zitat:

Eine Frage habe ich noch. Warum muss am Anfang TListBox = class (FMX.Listbox.TListbox); end; hinzugefügt werden? [...]
Das ist kein Muss. Wenn nur auf die public deklarierte Eigenschaften und Methode bzw. published deklarierte Eigenschaften programmseitig zugegriffen wird, dann ist es unsinnig.
Ich wollte aber auf die Scrollbars der ListBox zugreifen. Die sind aber in der Klasse TScrollBox als protected deklariert (und werden weder in TCustomListBox noch TListBox published), daher ist Zugriff nicht möglich (Stichwort Sichtbarkeit von protected Eigenschaften/Mehtoden: von Aussen nein, innerhalb der Unit ja).
Du kannst Dir den Zugriff auf die Scrollbars auch über einen class helper (in der OH unter: Unterstützende Klassen) bauen, das geht z. B. so:

Delphi-Quellcode:
type
  TListBoxHelper = class helper for FMX.ListBox.TListBox
  private
    function GetVertScrollBar : TScrollBar;
  published
    property VertScrollBar : TScrollBar read GetVertScrollBar;
  end;

function TListBoxHelper.GetVertScrollBar;
begin
  Result := Self.VScrollBar
end;
und der Zugriff dann so:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  ListBox1.VertScrollBar.Value := 40
end;
Gruß

Peter-Pascal 27. Jan 2014 15:23

AW: TGrid in FM mit Daten füllen
 
Hallo Volker,

ich glaube, dass ist die beste Idee mit den TCallOutRectancle zu arbeiten. Es muss halt nur die Position berechnet werden. Und genau dass hoffte ich mit TListBox zu vermeiden. Aber wenn ich mir jetzt Deine Bilder anschaue, muss ich erkennen, es sieht besser aus.

Vielen Dank für Deinen Vorschlag. Ich habe in den letzten Dialogen viel über FMX gelernt.

Gruß Peter


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:47 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 by Thomas Breitkreuz