![]() |
dynamisches Erstellen von Oberfläche und Speicherung in DB ?
Hallo @ all,
ich habe eine Sehr große Bitte an euch. Ich muss ein Programm schrieben, dem ich mich im Moment leider nicht gewachsen fühle. :cry: Im Endeffekt soll es eine Art einfache Favoritenliste zum Emails verschicken werden und später noch weiter ausgebaut werden. Man soll nach starten des Programms Reiter und somit weiter Blätter/Oberflächen (,die aber alle gleich sein sollen) dem Formular zufügen können. Im Moment denke ich mir, dass ich das nur mit einer Datenbank lösen kann. Ich habe leider noch nie mit so etwas dynamischen und Datenbanken aus Delphi raus gearbeitet. Deshalb erhoffe ich mir hier von euch ein bisschen Hilfe. Hier mal die Aufgabenstellung, kombiniert mit meinen Gedanken, wie man das Programm angehen könnte: Das Programm soll eine lokale Datenbank (es soll also kein Server laufen) erstellen und diese beim Programmstart immer abfragen. Über einen Menuepunkt (oder Rechtsklick, o.ä.) sollen Reiter (z.B. mit den Komponenten TabContol oder PageControl) erstellt werden können. Beim erstellen der Reiter muss dann auch die Reiterbeschriftung eingegeben werden können. Gleichzeitig soll für jeden angelegten Reiter eine Tabelle angelegt werden. Die Belegung jedes Reiters soll gleich sein und aus 10 Buttons bestehen. Deshalb müssen alle Tabellen auch gleich aufgebaut sein. Die Caption jedes Buttons soll am Anfang z.B. “nicht Belegt“ sein. Über einen Rechtsklick auf den Button möchte ich dann den jeweiligen Button belegen. Heißt, eine Eingabemaske soll aufpoppen und man kann Name, Vorname, und Emailadresse eintragen. Caption des Buttons soll dann z.B. der Name sein. Diese Daten sollen dann in der Datenbank, in der Tabelle des Reiters, in der Zeile des Buttons gespeichert werden. Beim nächsten Aufruf des Programms sollte die Reiter- und Buttonbelegung dann natürlich wieder auftauchen, da er es ja aus der Datenbank lesen sollte. ;) (Ein klick auf einen dieser Buttons soll im späteren Programm dann z.b. über “mailto“ das Empfängerfeld des Standart Email Programms füllen [ist ja kein Problem]) Hoffe ihr habt das so verstanden. Wenn nicht, fragt mir Löcher in den Bauch ;) Ich weiß, dass es schon etwas ziemlich kompaktes und für mich leider sehr schweres ist (was mir im Moment auch leider viele Bauchschmerzen bereitet), hoffe aber trotzdem auf Hilfe/Unterstützung eurerseits, da es vielleicht für den ein oder anderen nur “Kinderkram“ ist. Freue mich über jede Hilfe und jeden Tipp (wie z.B. Wahl der richtigen Datenbank, Lösung des Problems/Anregungen die Dynamik dort rein zu bekommen, u.s.w) Danke schon mal im Vorraus, Berndd [P.S. da ich nicht genau weiss, ob das Thema hier richtig ist, bitte ich einen Mod/Smod/Admin dies zu verschieben, falls es woanders besser passt. Danke] |
Re: dynamisches Erstellen von Oberfläche und Speicherung in
Hi,
also zum einen mal herzlich willkommen in der Delphi-Praxis ;-) Tja, das ist ein ganz schönes Ding. Leider hast Du nicht geschrieben, welche Delphi-Version Du verwendest, also mal zum elementaren: Zur Datenbank: Ohne Datenbankserver wird's schwierig ;-) Zumindest lokal sollte einer laufen. Natürlich gibt es so Sachen wie filebasierte Datenbanken, aber das ist immer ein wenig tricky. Wenn Du z.B. MS Office hast empfehle ich gerne die MSDE (Microsoft SQL Desktop Engine). Das ist der kleine Bruder vom SQL-Server der nicht so viel Performance hat wie der echte und bei 2 Gigabyte Datenbankgröße die Segel streicht, ist aber für Nutzer von MS Office kostenlos und kann alles was das Herz begehrt. Zum Verbinden und damit arbeiten guckst Du nach ![]() Ansonsten ist auch der Griff zu MySQL nicht schlecht, denn die ist klein, ressourcensparend, schnell und gibts im Netz kostenlos ;-) Zur Dynamik: Um dynamische Komponenten anzulegen gibts hier schon ne Menge im Forum. Such einfach mal im Bereich ![]() ![]() Zum Ablauf: Ansonsten würde ich tatsächlich mit einem Formular anfangen und erstmal die Verwaltung der Controls dynamisch machen (erstmal das erzeugen). Im zweiten Schritt würde ich die aktuelle Konfiguration (wiederfinden und 'merken') dann über ein TIniFile machen. Inidateien bieten sich hier an: Du hast eine beliebige Zahl an Reitern (Sections) mit einigen Buttons und deren Values. Du kannst also alle Informationen in einer Ini-Datei strukturiert ablegen. Im dritten Schritt geht man dann hin, liest die Informationen aus dem Inifile aus und baut daraus wieder den Ursprungszustand zusammen. Erst im letzten Schritt würde ich dann hergehen und die Informationen die im Ini-File liegen in die Datenbank zu stecken. Ich denke, so kann man sich vom leichten (dynamische Controls) über die dynamische Organisation von Informationen (Ini-File) bis hin zum Thema Datenbanken durchhangeln. |
Re: dynamisches Erstellen von Oberfläche und Speicherung in
Wie du Komponenten zur Laufzeit erstellst, kannst du hier nachlesen:
![]() Was das Speichern der Einstellungen angeht, halte ich eine Datenbank für übertrieben. Die "modernste" Möglichkeit wäre wohl eine XML-Datei. Dazu findest du auf ![]() [EDIT=Niko]Hm, hätte vielleicht vor dem Schreiben F5 drüchen sollen ... :roll: [/EDIT] |
Re: dynamisches Erstellen von Oberfläche und Speicherung in
Hi.
IMO müssen keine componenten dynamisch erstellt werden, da ja jedes tab gleich aussehen soll. Ein TTabControl, bei dem man anhand des indices entscheidet was man in der tabelle zeigt, würde es auch tun -> spart viel arbeit (imo). Und ne DB für ein paar mail-addys? Ich persöhnlich verwende gerne collections, die dann halt immer komplett im speicher liegt, erst recht seitdem ich einen weg gefunden habe diese auf platte zu streamen (DFM style)! Wenn dich das interessiert dann kannstu hier mal schauen, ob dir das nützt: ![]() Jedes collectionItem wäre dann ein datensatz! Dann machste für jedes tab eine collection-datei und fertig ist die laube :-D cu. |
Re: dynamisches Erstellen von Oberfläche und Speicherung in
borch, erstmal danke euch allen für die netten und kompetenten Antworten.
Da habe ich nun ja einiges erstmal nachzulesen. Zitat:
Naja, aber wenn Enterprise absolut nötig ist, dann denke ich, dass ich sie doch weiter nutzen kann und jemand anderes seine Enterprise gegen Professional tauschen muss. Müsste aber mit beiden Version machbar sein, oder ? Werde mich dann erstmal ein bischen in die vorgeschlagenen Datenbanken und Speicher Varianten einlesen. Sowohl XML, als auch die Streamingvariante hören sich auch sehr interesant an. Muss mich da dann aber erstmal komplett einarbeiten. Es darf lokal allerdings kein Server laufen. MSDE und MySQL brauchen ja nen eigenen Server, oder? Zitat:
Am liebsten würde ich nicht den Umweg über die iniFiles gehen. Aber das wird sich dann noch zeigen, ob ich ohne auf die Schnauze falle. :wink: Habe mich nun auch mit dem dynamischen Erstellen von Komponenten befasst. Kann schon die Buttons in der Laufzeit erstellen. Bekomme es aber leider absolut nicht hin, diese anzusprechen(/ihnen OnClick ereignisse zuzuweisen) oder sie auf die TabControls Komponente zu bringen. Das is schon das nächste Problem, die TabControls Komponente. Wie kann ich bei dieser in der Laufzeit neue Tabs/Reiter erstellen, den einzelnen Tabs Namen zuweisen und die Buttons gleichzeitig drauf platzieren. Zitat:
Kann mir nämlich nicht soooo viel darunter vorstellen :oops: Wäre echt nett von Dir/Euch. Wiedermal Danke im Vorraus, Berndd |
Re: dynamisches Erstellen von Oberfläche und Speicherung in
Hallo,
du sagtest: Zitat:
Jedes TTabControl hab ein onChange event, das ausgelöst wird sobald ein anderes tab angewählt wurde. Dort könntest du dann die daten in die addressliste laden. Du musst nur wissen welche daten, dazu schlage ich vor einen ID-wert in die 'tag'-property jedes, danymisch erstellten, tabs zu schreiben....den du dann als suffix für die dateinamen nimmst. Und als container für die addressdaten sind collectionItems nicht schlecht, da sie eigegebenen daten noch korrigieren können (set methode). Letztendlich musst du das mit dir ausmachen :wink: cu. max. PS: noch besser: ...TTabControl.tabs ist eine stringListe! DH. du könntest jedem tab direkt ein TmxCollection-object anhängen, dann kannst du TTabControl.tabIndex die aktuelle liste rausfinden..oder so. |
Re: dynamisches Erstellen von Oberfläche und Speicherung in
Zitat:
Delphi-Quellcode:
Beim erstellen der Buttons machst Du ja sowas wie:
procedure TForm1.DynButtonClick(sender: TObject);
begin if sender is TButton then begin // hier die Methodik - z.B. Button erkennen end; end;
Delphi-Quellcode:
Der Code ist freilich nicht getestet, sollte aber den Ablauf prinzipiell erklären. Die Methode wird übrigens für _jeden_ Button zugewiesen, d.H. Du musst tatsächlich über den Sender herausfinden, welcher Button gedrückt wurde.
var
myVar: TButton; begin myVar := TButton.Create(self); myVar.Parent := TTabPage1; // der 'Parent' ist die TabPage, auf der der Button erscheinen soll myVar.OnClick := DynButtonClick; // hier die OnClick - Methode. myVar.Name := 'Button'; // anhand des Namens kannst Du oben in der OnClick - Methode den Button identifizieren: ( TButton(sender).Name ) end; Ich würde in Deinem Fall empfehlen, den Button eine Konstante und eine durchlaufende Nummer zu geben. Mit ![]() |
AW: dynamisches Erstellen von Oberfläche und Speicherung in DB ?
Hallo,
ich finde das Thema sehr interessant! Grundsätzliche habe ich aber 2-3 Verständnisfragen: 1. Bei "myVar := TButton.Create(self);" Wie speichere ich "TButton.Create(self)" in der DB ab und wie kann ich das dann nachher aus der DB an myVar zuweisen? 2. Wie kann ich das was eine "OnClick-Procedure oder -Function" machen soll - ebenfalls aus der DB holen und zuweisen? Vielen Dank vorab! Beste Grüße mbulm1 |
AW: dynamisches Erstellen von Oberfläche und Speicherung in DB ?
Ich für meinen Teil mache das schon seit Jahren so in der Art, aber bei mir sind Tabellenfelder immer der Grund dafür, das es bestimmte Controls gibt, text blobs werden als Tmemo erzeugt, varchar als TEdit, Datum als TDateEdit usw.
Alle Infos bekommst du auf dem Weg über die TField Objekte aus einem Dataset, wenn du einfach mit select * from tabelle die Daten holst und dann auf dem offenen Dataset durch fields[i] gehst mit i<fieldcount. Das TField Objekt liefert dir ggf über die Property classname ausreichend Infos, um dann zu entscheiden was kommen soll (für jedes Feld erzeuge ich dann auch noch automatisch ein TLabel als Caption). In der DB hab ich dann in einer tabelle die positionen gespeichert, das sieht dann in etwa so aus
Code:
Beim Erzeugen des Formulars lese ich die Daten aus dem Datenbankfeld Blob Sub_type text die daten in eine TStringlist und über Feldname und Komponenten Präfix such ich mir aus der TStringlist mit Values dann die Werte raus, die mein Code zum jeweiligen Feld bereits kennt (Meinen Eintrag .HILFE kann man zB. im Hint oder in einer Statusbar anzeigen, die kann der Endkunde selber ergänzen).
cbxARCLADEN_CB.LEFT=178
cbxARCLADEN_CB.TOP=950 cbxARCLADEN_CB.WIDTH=26 cedARBEITSGANG_POSDIFF.HILFE=leeres Feld = Ag an letzter Stelle , -1 = AG an vorletzter Stelle etc. cedARBEITSGANG_POSDIFF.LEFT=439 cedARBEITSGANG_POSDIFF.TOP=438 cedARBEITSGANG_POSDIFF.WIDTH=56 cedAUSLASTUNGMAPROZ.HILFE=Zu wieviel % seiner Arbeitszeit ist der AV hier beschäftigt? cedDLZ.HILFE=auf 1 setzen, um neu zu berechnen cedDLZ.LEFT=440 cedDLZ.WIDTH=55 dteBELEGDATUM.LEFT=112 dteBELEGDATUM.TOP=30 dteBESTELLDATUM.LEFT=112 dteBESTELLDATUM.TOP=346 dteLIEFERTERMIN.LEFT=112 dteLIEFERTERMIN.TOP=865 edtAB_CALC.LEFT=113 edtAB_CALC.TOP=731 edtAB_CALC.WIDTH=77 edtANGEBOT_ID_.HILFE=Verknüpfung löschen: Shift + Lupe / leer suchen / leer übernehmen edtANGEBOT_ID_.LEFT=114 edtANGEBOT_ID_.TOP=692 edtANGEBOT_ID_.WIDTH=226 edtARBEITSVORBEREITUNG_ID_.LEFT=112 edtARBEITSVORBEREITUNG_ID_.TOP=318 edtARBEITSVORBEREITUNG_ID_.WIDTH=48 Die Properties kannst du dir ggf. alle durch eine Objektinspektor Komponente anzeigen lassen oder so wie ich das mach, einfach nur some basic functions wie positionieren erlauben (bei meiner Software schaltet der Kunde, sofern berechtigt, die exe in den Designmode, klickt die Felder an, die er neu positionieren möchte (die wechseln dann einfach in background color rot und werden bei onclick in eine TList gepackt. Mit Ctrl+Cursortasten kann er nun left und top aller gewählter Komponenten pixelweise verändern und mit Alt+cursortasten height und width. Wenn er zurück vom Deignmodus in den Normalmodus schaltet, klapper ich auf dem Form alle components[i] bis i<componentcount ab und schreib die mir relevanten eigenschaften zurück die die TStringlist Values und den kompletten inhalt wieder zurück in die DB, so das dann beim nächsten Aufbau des Formulars die position in onshow wieder so legen kann, wie der Kunde das wollte, ohne das ich irgendwas neu compilieren muss. Mein Kunde (der keine Programmierkenntnisse hat) nutz das Verfahren gerne und stellt sich die Formulare damit so um wie er will. Teilweise werden unwichge Felder hinter andere gelegt, man könnte aber auch visible unterstützen etc. Der Vorteil, das über die Datenbankfelder zu machen liegt darin, das du die zum Speichern ggf eh brauchst und ich neue Felder in einer Tabelle ergänzen kann und die sofort beim nächsten Aufruf im Form sind. Wenn die noch keine Positionsdaten in der o.a. TStringlist haben, werden die einfach sequentiell am Ende vom Form angelegt. Taborder läuft bei mir über die Eigenschaft top, also immer von oben nach unten. Von Hand eingetragen werden zum Beispiel Attribute wie Readonly wenn sich die nicht eh schon aus dem TField ergeben und die brauchen eh kein Tabstop. Es hindert dich aber auch niemand dran, einfach mal ein eigenes Format zu entwickeln und dabei dann einfach so was wie Edit1=TEdit Label2=TLabel aus einem Text auszulesen und durch if then else oder andere Konstrukte passende Instanzen zu erstellen (in der TStringlist kannst du mit names[i] finden wie der Eintrag heisst und mit values[i] dann eben sehen, was rechts neben dem gleich steht). wenn der Kram aber auch irgendwo in einer DB gespeichert werden soll muss ggf dein code auch das anpassen oder erstellen der Tabellen mit übernehmen, so das 2 Referenzen zusammen passen müssen. Mein Ansatz ermöglicht es, völlig unterschiedliche Datenmodelle mit der gleichen exe zu öffnen und zu visualisieren, Ich hab meine Exe daher im Prinzip so ähnlich ausgelegt wie ein webbrowser, nur das der eben nicht mit html/http/webserver kommuniziert, sondern direkt mit einer DB. |
AW: dynamisches Erstellen von Oberfläche und Speicherung in DB ?
wenn du mehr auf fertige Komponenten setzen willst, dann schau dir zum Beispiel diese varianten an
![]() ![]() Damit kannst du nahezu alles unbegrenzt zur Laufzeit machen, aber eigentlich ist man dann ganz schnell auf dem Level, das der Anwender der eigenen Software, der diese Features benutzen soll, das gleiche wissen muss wie du selber |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:42 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-2025 by Thomas Breitkreuz