![]() |
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 |
AW: TGrid in FM mit Daten füllen
Hallo,
Zitat:
Delphi-Quellcode:
weiter.
TGrid.OnGetValue
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:
Füllt Dir die Zeilen dann mit der der Grafik aus dem TImage
procedure TForm1.Grid1GetValue(Sender: TObject; const Col, Row: Integer; var Value: TValue);
begin if Col = 0 then Value := Image1.Bitmap end; Gruß |
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 |
AW: TGrid in FM mit Daten füllen
Hallo,
Zitat:
SetValue immer dann, wenn der Anwender den Zelleninhalt ändert. Zitat:
![]() Zitat:
Delphi-Quellcode:
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. ä.)
ImageColumn1.Children [i].Data := Image1.Bitmap
Zitat:
Vielleicht hilft' s Gruß |
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 |
AW: TGrid in FM mit Daten füllen
Hallo,
Zitat:
Gruß |
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. |
AW: TGrid in FM mit Daten füllen
Hallo,
Zitat:
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):
Delphi-Quellcode:
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).
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. Vielleicht hilft 's weiter oder ein Kollege hat 'ne bessere Idee. Gruß |
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 |
AW: TGrid in FM mit Daten füllen
Hallo,
Zitat:
Zitat:
Delphi-Quellcode:
vor der Deklaration des Forms).
TListBox = class (FMX.ListBox.TListBox)end;
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ß |
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 |
AW: TGrid in FM mit Daten füllen
Hallo,
Zitat:
Ich kann es leider nicht nachbilden und testen - Grund: fehlendes Finger-Fummel-Gerät. Gruß |
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:
solltest Du das synchronisiert bekommen. Vielleicht ergibt sich dabei auch etwas in Sachen Touchproblem.
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; Gruß |
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 |
AW: TGrid in FM mit Daten füllen
Hallo,
Zitat:
Zitat:
Zitat:
Ich kann es zwar nicht mit Wischen, aber ich habe mal versucht das mit der Maus nachzubilden:
Delphi-Quellcode:
das Wischverhalten nachbilden und die beiden Scrollboxen synchronisieren.
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; Vielleicht hilft Dir das Beispiel Deine Listboxen (die sind ja letztlich von TScrollBox abgeleitet) zu synchronisieren. Zitat:
Gruß |
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 |
AW: TGrid in FM mit Daten füllen
Hallo,
Zitat:
Gruß |
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:
Ich habe eine neue Anwendung erstellt: Firemonkey-Anwendung für Metropolis UI Delphi - anschließend Leere Metropolis-UI Anwendung.
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. Den Gesturemanager habe ich bei der Scrollbox eingehakt. Gruß |
AW: TGrid in FM mit Daten füllen
Hallo,
Zitat:
Ich konnte Dein Problem mal nachstellen (vermute ich mal). Wenn die Metropolis UI Anwendung mit der Eigenschaft
Delphi-Quellcode:
(Standardeinstellung, hatte ich geändert :oops:) läuft, dann werden die Gesten offenbar nicht getriggert.
FullScreen := True
Abhilfe schafft
Delphi-Quellcode:
. Wo der Unterschied genau liegt und was es für Auswirkungen hat muss ich erst noch untersuchen.
BorderStyle := bsNone
Gruß |
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 |
AW: TGrid in FM mit Daten füllen
Hallo,
Zitat:
Hast Du es mit
Delphi-Quellcode:
und
FullScreen := True
Delphi-Quellcode:
schon versucht?
BorderStyle := bsNone
Gruß |
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 |
AW: TGrid in FM mit Daten füllen
Hallo,
Zitat:
Zitat:
Gruß |
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 |
AW: TGrid in FM mit Daten füllen
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo,
Zitat:
Zitat:
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:
und der Zugriff dann so:
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;
Delphi-Quellcode:
Gruß
procedure TForm1.Button1Click(Sender: TObject);
begin ListBox1.VertScrollBar.Value := 40 end; |
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