Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   Delphi [FMX] Combobox per Code mit Daten füllen (https://www.delphipraxis.net/191652-%5Bfmx%5D-combobox-per-code-mit-daten-fuellen.html)

Devil1925 7. Feb 2017 08:15

[FMX] Combobox per Code mit Daten füllen
 
Moin, Ich habe da mal eine Problemstellung, an der ich gerade nicht vorbei komme.

Problemstellung: Ich habe eine Listbox, in welcher Dynamisch verschiedene Listboxitems erstellt werden, welche verschiedene Componenten enthalten (TSwitch, TEdit, etc.). Das Funktioniert auch soweit ganz gut. Allerdings muss ich jetzt auch TCombobox integrieren. Das erstellen klappt, aber wie bekomme ich jetzt meine Daten da rein? Die Query für die Daten wird ebenfalls dynamisch erstellt.

Darlo 7. Feb 2017 08:34

AW: [FMX] Combobox per Code mit Daten füllen
 
Eigentlich sehr einfach.

Delphi-Quellcode:
 
for i := 0 to sl.Count-1 do
   self.combobox.Items.Add(sl[i]);

Devil1925 7. Feb 2017 08:41

AW: [FMX] Combobox per Code mit Daten füllen
 
an die Methode habe ich auch schon gedacht, nur wie komme ich jetzt an die anderen Daten ran, welche zu diesem Datensatz gehören? ich finde es sehr unglücklich über das Anzeige-Feld in der Query zu suchen.

Sherlock 7. Feb 2017 08:43

AW: [FMX] Combobox per Code mit Daten füllen
 
Du musst Dir eventuell einen Weg ausdenken, die ComboBoxen zu identifizieren, aber das ist eigentlich fast schon trivial über
Delphi-Quellcode:
Tag
oder
Delphi-Quellcode:
TagString
lösbar.

Sherlock

Aviator 7. Feb 2017 08:45

AW: [FMX] Combobox per Code mit Daten füllen
 
Zitat:

Zitat von Sherlock (Beitrag 1360982)
Du musst Dir eventuell einen Weg ausdenken, die ComboBoxen zu identifizieren, aber das ist eigentlich fast schon trivial über
Delphi-Quellcode:
Tag
oder
Delphi-Quellcode:
TagString
lösbar.

Sherlock

Ich glaube er meint eher, wie er aus einem Eintrag den eigentlichen Datensatz aus der Query wiederfinden kann. Bei der VCL hätte man sowas mit den Items.Objects der ComboBox gemacht. Ob das bei FMX gleich/ähnlich ist weiß ich allerdings nicht.

Darlo 7. Feb 2017 08:51

AW: [FMX] Combobox per Code mit Daten füllen
 
Zitat:

Zitat von Devil1925 (Beitrag 1360981)
an die Methode habe ich auch schon gedacht, nur wie komme ich jetzt an die anderen Daten ran, welche zu diesem Datensatz gehören? ich finde es sehr unglücklich über das Anzeige-Feld in der Query zu suchen.

Zitat:

Zitat von Sherlock (Beitrag 1360982)
Du musst Dir eventuell einen Weg ausdenken, die ComboBoxen zu identifizieren, aber das ist eigentlich fast schon trivial über
Delphi-Quellcode:
Tag
oder
Delphi-Quellcode:
TagString
lösbar.

Sherlock

Ich nutze auch TagString um den PK des Datensatzes zu hinterlegen.

himitsu 7. Feb 2017 09:06

AW: [FMX] Combobox per Code mit Daten füllen
 
Zitat:

Zitat von Darlo (Beitrag 1360980)
Delphi-Quellcode:
for i := 0 to sl.Count-1 do
  self.combobox.Items.Add(sl[i]);

Etwas wie
Delphi-Quellcode:
ComboBox.Items.AddStrings(SL);
gibt es im FMX nicht?

Aber bei
Zitat:

Zitat von Devil1925 (Beitrag 1360979)
Die Query für die Daten wird ebenfalls dynamisch erstellt.

könnte man auch direkt an eine DB-Verbindung nachdenken (wenn die Query bestehen bleibt die Daten die ganze Zeit geladen bleiben), also per LiveBinding die ComboBox an die Query binden.

Devil1925 7. Feb 2017 09:36

AW: [FMX] Combobox per Code mit Daten füllen
 
zum Thema Livebindings: kann man die so ohne weiteres Setzen im Code? weil ich ja nicht im vorraus schon weis wie viele Comboboxen ich habe und dementsprechend wie viele Querys ich generiere.

Sherlock 7. Feb 2017 10:55

AW: [FMX] Combobox per Code mit Daten füllen
 
Sind LiveBindings mittlerweile alltagstauglich? Ich hörte noch im letzten Jahr gegenteiliges. Vergleiche dazu http://www.delphipraxis.net/190729-w...ebindings.html und den daran angeschlossenen G+ Thread.

Sherlock

haentschman 7. Feb 2017 11:26

AW: [FMX] Combobox per Code mit Daten füllen
 
Moin...:P
Zitat:

Sind LiveBindings mittlerweile alltagstauglich?
[meine Meinung]
Ich habe es mal probiert... Ich hatte mir erhofft das der QT übersichtlicher wird und das Verdrahten der visuellen Controls ein einfacher sein müßte...
Versuch:
Visuelle Controls an eine generische Liste mit Objekten hängen: Im Ergebnis habe ich mehr Code Zeilen gehabt und die Übersicht hat gelitten. Der klassische Weg war deutlich einfacher. Schade drum... :?
[/meine Meinung]

Darlo 7. Feb 2017 12:41

AW: [FMX] Combobox per Code mit Daten füllen
 
[QUOTE=himitsu;1360986]
Zitat:

Zitat von Darlo (Beitrag 1360980)
Delphi-Quellcode:
for i := 0 to sl.Count-1 do
  self.combobox.Items.Add(sl[i]);

Etwas wie
Delphi-Quellcode:
ComboBox.Items.AddStrings(SL);
gibt es im FMX nicht?

Natürlich. Vermutete nur dass die Schleife für den Anwendungsfall passender ist.

Devil1925 7. Feb 2017 13:03

AW: [FMX] Combobox per Code mit Daten füllen
 
Also mir ist bisher halt nur der Weg für die direkte verbindung von Query (TUniQuery) und einer Combobox (TComboBox) über die Livebindings bekannt, welche im Designer erstellt werden. Wenn mir da jemand erklären könnte wie man die Codetechnisch erzeugen kann / mir dafür ein gutes Tutorial empfehlen kann, wäre ich diesem jemand sehr Dankbar!

Alternativ lasse ich mich auch gerne belehren über alternative sinnvolle möglichkeiten die Daten aus einer UniQuery in eine ComboBox einzufügen. Wie ich das mit einer Stringlist machen soll habe ich noch nicht verstanden, ich wäre jetzt mit einer Schleife die Query durchgegangen und hätte jeden eintrag einzeln in der Combobox angelegt. Allerdings erscheint mir das eher weniger sinnvoll. (Oder irre ich mich da?)

Devil1925 15. Feb 2017 08:06

AW: [FMX] Combobox per Code mit Daten füllen
 
Mein Bisheriger Versuch sieht folgendermaßen aus und funktioniert leider nicht, kann mir da jemand verraten, wo ich da meinen Fatalen Fehler mache?

(Ich vermute irgendwo in der zuweisung Link zu Combobox)

Delphi-Quellcode:
procedure TForm14.Button2Click(Sender: TObject);
var BS:TBindSourceDB;
    CB:TCombobox;
    Link:TLinkListControlToField;
    Query:TUniQuery;
begin
  Query := TUniQuery.Create(Self);
  Query.Connection := Conn;
  Query.SQL.Text := 'Select * from Lieferan';
  Query.Open;


  BS := TBindSourceDB.Create(Self);
  BS.DataSet := Query;

  CB := TCombobox.Create(Rectangle1);
  CB.Parent := Rectangle1;

  Link := TLinkListControlToField.Create(Self);
  Link.AutoActivate := True;
  Link.Category := 'Schnelle Bindung';
  Link.Control := CB;
  Link.DataSource := BS;
  Link.FieldName := 'Name1';

  BS.DataSet.Open;
end;

Devil1925 15. Feb 2017 15:13

AW: [FMX] Combobox per Code mit Daten füllen
 
irgendwer eine Idee / einen Stoß in die richtige Richtung oder ähnliches? oder ist es wirklich das Sinnvollste die Query Datensatz für Datensatz zu durchlaufen?

Rollo62 15. Feb 2017 16:21

AW: [FMX] Combobox per Code mit Daten füllen
 
Wenn du die Verbindung mit LiveBindings-Editor machst legt der LB-Editor die entsprechenden Komponenten richtig an.
Die kannst du dir mal anschauen im Dfm.Modul in der Text-Ansicht, und das dann womöglich zur Laufzeit von Hand selber schreiben, wenn es das ist was du meinst ?

Ansonsten die ComboBox wirklich von Hand, ohne LiveBindings beschreiben.
Mit durchlaufen von Dataset.First, Dataset.Next, etc.

Rollo

Devil1925 16. Feb 2017 08:05

AW: [FMX] Combobox per Code mit Daten füllen
 
Danke an alle, die mir input gegeben habe! Ich habe nun eine Funktionierende Lösung!

Delphi-Quellcode:
procedure TForm14.FillList(DataSet:TUniQuery; Control:TControl; FieldName:String);
var
    BindSourceDB : TBindSourceDB;
    BindingsList : TBindingsList;
    LinkListControlToField : TLinkListControlToField;
begin

    BindSourceDB := TBindSourceDB.Create(nil);
    BindSourceDB.DataSet := DataSet;
    BindSourceDB.DataSource.Enabled := true;
    BindSourceDB.DataSet.Active := true;

    BindingsList := TBindingsList.Create(BindSourceDB);

    LinkListControlToField := TLinkListControlToField.Create(BindingsList);
    LinkListControlToField.Control   := Control;
    LinkListControlToField.DataSource := BindSourceDB;
    LinkListControlToField.FieldName := FieldName;
    LinkListControlToField.Active    := true;
end;
gefunden habe ich die gerade hier.

himitsu 16. Feb 2017 11:00

AW: [FMX] Combobox per Code mit Daten füllen
 
Für ein schöneres Debugging, sollte man seinen Kompoennten immer einen Namen geben.
Und wer gibt bei dieser Variante das ganze wieder frei, wenn der Owner leer ist?

Mit einem Namen kann man beim Debuggen erstmal sehen, wen man in den Pfoten hat, wenn man 'nen Zeiger auf "irgendein" Control hat.
Und man kann hier z.B. eine Prüfung einbauen.
Delphi-Quellcode:
procedure TForm14.LinkToControl(Control: TControl; DataSet: TDataSet; FieldName: string);
var
  DataName: string;
  BindSourceDB: TBindSourceDB;
  BindingsList: TBindingsList;
  LinkListControl: TLinkListControlToField;
begin
  DataName := DataSet.Name;
  if (DataName = '') and Assigned(DataSet.DataSource) then
    DataName := DataSet.DataSource.Name;

  if Assigned(Control.FindComponent(DataName + '_BindSource')) then
    raise Exception.CreateFmt('LinkToControl: %s.%s ist bereits an %s (%s) gebunden.', [DataName, FieldName, Control.Name, Control.ClassName]);

  BindSourceDB := TBindSourceDB.Create(Control);
  BindSourceDB.Name              := DataName + '_BindSource';
  BindSourceDB.DataSet           := DataSet;
  BindSourceDB.DataSet.Active    := True; // das Beides hat hier doch eigentlich nichts zu suchen
  BindSourceDB.DataSource.Enabled := True; //

  BindingsList := TBindingsList.Create(BindSourceDB);
  BindingsList.Name              := DataName + '_BindingsList';

  LinkListControl := TLinkListControlToField.Create(BindingsList);
  LinkListControl.Name           := DataName + '_LinkListControl';
  LinkListControl.Control        := Control;
  LinkListControl.DataSource     := BindSourceDB;
  LinkListControl.FieldName      := FieldName;
  LinkListControl.Active         := True;
end;

Devil1925 16. Feb 2017 13:00

AW: [FMX] Combobox per Code mit Daten füllen
 
Danke für Deine Mühe! Werde ich sofort mal umsetzen :D und jetzt noch eine Frage für die Verständlichkeit meinersets...

Wenn ich jetzt das Control Frei gebe, wird dann auch alles andere Freigegeben? also BindsourceDB, Bindingslist und LinkListControl?

Mavarik 16. Feb 2017 13:38

AW: [FMX] Combobox per Code mit Daten füllen
 
Zitat:

Zitat von Devil1925 (Beitrag 1361831)
Danke für Deine Mühe! Werde ich sofort mal umsetzen :D und jetzt noch eine Frage für die Verständlichkeit meinersets...

Wenn ich jetzt das Control Frei gebe, wird dann auch alles andere Freigegeben? also BindsourceDB, Bindingslist und LinkListControl?

Gibt es einen besonderen Grund, warum Du es unbedingt - wenn du es eh schon im Source machst - über die Livebindings machen willst?

Abgesehen von den ganzen lokalen Variablen inkl. der Datenbank Geschichten?

Devil1925 16. Feb 2017 13:57

AW: [FMX] Combobox per Code mit Daten füllen
 
Ich kenn in FMX als Möglichkeit nur die Livebindings, wenn du noch andere (bessere?) Methoden kennst, lasse ich mich gerne Aufklären :-D

für mich sieht die Methode des durchlaufens der Query in einer Schleife (First, Next) halt danach aus, als wäre es deutlich langsamer als die LiveBindings. Ausserdem kann ich dann doch direkt (bei z.B. Edit-Feldern) den geänderten Wert per "Post" in die Datenbank schreiben. Wenn ich da einen Denkfehler habe, so kläre mich doch bitte auf :D

Danke

Rollo62 16. Feb 2017 14:36

AW: [FMX] Combobox per Code mit Daten füllen
 
Das hier ist auch ganz sehenswert zu LB.

LB per Code funktioniert bei mir auch ganz gut.
Habe allerdings auch kaum anspruchsvolle DB im Mobilteil, unter Sqlite.
Ist mir auch sympatischer als das LB-Editor Stripenziehen.
Wenn da mal was verrutscht (z.B. bei Updates) dann ist die Übersicht komplett vorbei.

Um damit auf die Art aber größere DB-Projekte zu machen ... naja ...
wäre ich zumindest vorsichtig :stupid:

Rollo

Mavarik 16. Feb 2017 17:09

AW: [FMX] Combobox per Code mit Daten füllen
 
Zitat:

Zitat von Devil1925 (Beitrag 1361845)
Ich kenn in FMX als Möglichkeit nur die Livebindings, wenn du noch andere (bessere?) Methoden kennst, lasse ich mich gerne Aufklären :-D

für mich sieht die Methode des durchlaufens der Query in einer Schleife (First, Next) halt danach aus, als wäre es deutlich langsamer als die LiveBindings. Ausserdem kann ich dann doch direkt (bei z.B. Edit-Feldern) den geänderten Wert per "Post" in die Datenbank schreiben. Wenn ich da einen Denkfehler habe, so kläre mich doch bitte auf :D

Danke

Besser ist immer so eine Frage... Ich würde es nur so NIE machen...

Delphi-Quellcode:
Procedure TForm14.FillCombobox(Const ACB : TCombobox;Const AFieldName : String);
var
  LBI     : TListBoxItem;
  LEntries : ICanHandleDBListFields;
  i       : Integer;
begin
  LEntries := Database.GetListFields(AFieldName);

  ACB.BeginUpdate;
  ACB.Clear;
  try
    for i:=0 to LEntries.count-1 do
      begin
        LBI       := NewListBoxEntry; // Erzeugt eine LBI mit Height=49 Stylelookup='listboxitembottomdetail' usw.
        LBI.Text  := LEnties.Items[i].Text;
        LBI.Detail := LEnties.Items[i].Detail;
        LBI.Parent := ACB;
      end;
  finally
    ACB.EndUpdate;
  end;
end;

himitsu 16. Feb 2017 18:02

AW: [FMX] Combobox per Code mit Daten füllen
 
Wenn die Owner richtig gesetzt sind, dann wird alles automatisch freigegeben.

Und jup, in FMX gibt es keine DB-affinen Controls, da muß man alles irgendwie anders Binden.
TDBEdit und Co. gibt es standardmäßig nur in der VCL und das sind auch nur TEdit, wo ein TDataLink intern dran hängt, der sowas wie das LiveBinding macht.

Rollo62 16. Feb 2017 19:21

AW: [FMX] Combobox per Code mit Daten füllen
 
Hallo Mavarik,

das ist auch nur ein Teil der Lösung.
Wenn es richtig bidirectional arbeiten soll, und z.B. auch auf
Updates von anderswoher reagieren soll wird es recht unangenehm.

Ich versuche erstmal mit LB zu leben und mich damit anzufreunden.
Funktionieren tut es in etwa, nur würde ich nicht zuviel erwarten bei komplexen Projekten.
Ich gehe aber stark davon aus das es in Zukunft weiter entwickelt wird, und einen
echten Ersatz für DB-Controls werden wird.
Zumal es ja auch unter VCL arbeitet wird das wohl so etwas wie Embas ORM-Lösung werden.
Ich bin gespannt.

Gibt es vielleicht 3rd-Party Controls die man besser für DB+FMX Binding nutzen sollte ?
Da weiss ich im Moment aber auch keine.

Rollo

Mavarik 16. Feb 2017 21:54

AW: [FMX] Combobox per Code mit Daten füllen
 
Zitat:

Zitat von Rollo62 (Beitrag 1361886)
Hallo Mavarik,

das ist auch nur ein Teil der Lösung.
Wenn es richtig bidirectional arbeiten soll, und z.B. auch auf
Updates von anderswoher reagieren soll wird es recht unangenehm.

Nö eigentlich nicht...

Seit ich MVVM für mich entdeckt habe stellt sich diese Frage irgendwie nicht mehr...

Was soll meine View mit irgend einer Datenbank Komponente?

Meine View macht nur das was sie soll... Mein ViewModel steuert das... Mein Model kennt die Daten und bekommt entweder über eine Factory oder
über den Constructor ein CRUD Interface für die Datenbank...

Alle getrennt, alles schick, alles testbar...

Abgesehen davon, dass es in den Schichten somit viel mehr Threading Möglichkeiten gibt, was das etwas mehr Kommunikationsoverhead deutlich wett-macht.
Somit ist alles schneller...

Mavarik

Rollo62 17. Feb 2017 06:30

AW: [FMX] Combobox per Code mit Daten füllen
 
Wenn der View nicht die Arbeit macht dann eben das ViewModel.
Irgendwo musst du ja die Logik reinbauen.
Womöglich hast du Wrapper-Klassen für jede Komponente, die das dann optimal machen.
Das wäre ja OK.

Vom Code unten frage ich mich wie du das machst wenn nur ein Record in
die DB "inserted" wird ?
Immer die ganze ComboBox neuanlegen/neuzeichnen lassen, oder lässt du da auch nur
das eine, richtige Item hinzufügen ?

Das immer komplett Alles neuzuzeichen fände ich ziemlich unperformant.

Rollo

Mavarik 17. Feb 2017 10:57

AW: [FMX] Combobox per Code mit Daten füllen
 
Zitat:

Zitat von Rollo62 (Beitrag 1361899)
Wenn der View nicht die Arbeit macht dann eben das ViewModel.
Irgendwo musst du ja die Logik reinbauen.
Womöglich hast du Wrapper-Klassen für jede Komponente, die das dann optimal machen.
Das wäre ja OK.

Vom Code unten frage ich mich wie du das machst wenn nur ein Record in
die DB "inserted" wird ?
Immer die ganze ComboBox neuanlegen/neuzeichnen lassen, oder lässt du da auch nur
das eine, richtige Item hinzufügen ?

Das immer komplett Alles neuzuzeichen fände ich ziemlich unperformant.

Rollo

Wenn ich die Zuweisung nicht selber mache nach dem Motto: Feld X hat sich geändert sende PropertyChangeEvent,
dann habe ich eine eigene Routine die eine View 1:1 an ein ViewModel "klöppelt". Wenn der User etwas eingibt,
wir automatisch die entsprechende Property im Daten-Bereich des ViewModel geändert. Andererseits wenn sich das Model ändert,
kann ich mit einem Refresh (1 Event) die View aktualisieren.

Das Ding mit der Combobox war ja wenn ich es richtig verstanden habe "nur" für Fetchlisten -> Hole alle Anreden aus der Datenbank.

Das füllen der Liste ist kein Thema und unter FMX wird ja per GPU nur das neu gezeichnet was auch sichtbar ist... wenn es nicht 10000 Einträge sind...
Kaum messbar.

Mavarik

PS.: Bei 10000 Einträgen würden man sowieso ne Listview nehmen oder einen eigenen Pager bauchen... Niemand scrollt durch eine Liste von 10000 Einträgen.

Devil1925 17. Feb 2017 12:41

AW: [FMX] Combobox per Code mit Daten füllen
 
Die verwendung war so gedacht: Hole alle Datensätze (seien es meinetwegen Anreden) aus der Datenbank und zeige sie mir in der Combobox an. Dann wird eins Ausgewählt aus der Combobox (in diesem bespiel sei es mal "Herr"). Danach brauche ich die Informationen die es sonst noch zu dem Datensatz gibt. Also z.B. Briefanrede, Anrede_Nr, etc.

Mavarik 17. Feb 2017 13:04

AW: [FMX] Combobox per Code mit Daten füllen
 
Zitat:

Zitat von Devil1925 (Beitrag 1361943)
Die verwendung war so gedacht: Hole alle Datensätze (seien es meinetwegen Anreden) aus der Datenbank und zeige sie mir in der Combobox an. Dann wird eins Ausgewählt aus der Combobox (in diesem bespiel sei es mal "Herr"). Danach brauche ich die Informationen die es sonst noch zu dem Datensatz gibt. Also z.B. Briefanrede, Anrede_Nr, etc.

Ja, so hatte ich es verstanden...

Also im OnChange der Combobox per TagObject, Tag oder was auch immer den Rest laden...

ggf. (Falls lokale DB) kannst Du nach dem die Combobox gefüllt ist eine Thread starten (vorausgesetzt die Auswahl ist begrenzt) und hier alle Möglichkeiten preloaden... Dann ist bei einem OnChange das Ergebniss sofort da...

Kommt aber stark auf die Anwendung an...

Mavarik

Devil1925 17. Feb 2017 13:33

AW: [FMX] Combobox per Code mit Daten füllen
 
OK, Danke :D Gucke ich mir bei gelegenheit mal genauer an ob das sinnvoll ist oder nicht... ich mache jetzt erstmal wochenende!

Vielen Dank für die Hilfe und einen schönen Wochenabschluss wünsche ich :cheers:


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:06 Uhr.

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