Umstieg von Delphi7 auf Visual C# 2010 (einige Fragen)



  • Hallo,

    nach etlichen Jahren bin ich nun doch an einem Punkt, an dem mir Delphi7 zu alt geworden ist. Daher möchte ich gern versuchen mich in C# einzuarbeiten.

    Dazu bitte ich um ein paar kleine Hinweise:

    1. In VC#2010 habe ich kein StringGrid gefunden, in welchem einzelne Zellen Strings zugewiesen werden können und im erweiterten Fall, wenn die Zeichnung des Grids selbst vorgenommen wird, sogar Bilder oder andere Objekte (CheckBox, Editfeld). Gibt es so etwas in VC# nicht ?

    2. In Delphi war ich gewohnt, dass ich Formularübergreifend arbeiten kann. So konnte ich z.B. einfach das Hauptformular verstecken und ein zweites anzeigen. Wenn das zweite nicht mehr benötigt wird, kann ich es schließen und das Hauptformular wieder anzeigen lassen.
    Probiert habe ich das in VC# auch, jedoch gab es ständig Fehler, dass Form1 innerhalb Form2 nicht bekannt sei oder Form1.Show(); bzw. Form1.Visible = True; konnte aus Form2 nicht aufgerufen werden.

    3. Wie regelt man in VC# die Formularübergreifenden Constanten/Variablen/Klassen? In Delphi habe ich mir dazu eigene Units angelegt, z.B. eine Unit für Variablen, welche Applicationweit gütlig waren. Für die anderen Dinge ebenfalls. Ist das in VC# auch erlaubt/gängig?

    4. Ein schönes Tutorial zum MS SQL Server als Embedded DB habe ich gefunden. Gibt es in VC# Express nur wenige visuelle Datenobjekte?

    5. Ist es mir möglich unter VC# 2010 so genannte eigene Komponenten zu erstellen, welche dann auf eine Form gepackt werden können - sichtbar und unsichtbar - und wenn ja, gibt es hierzu bitte ein Tutorial?

    Das waren erst einmal meine kleinen Fragen.
    Große folgen sicherlich später.

    Vielen Dank für das Lesen, eine schöne Osterzeit 🙂



  • 1. DataGridView in Winforms

    2. Die Fensterverwaltung musst Du selbst übernehmen und muss in größeren Anwendungen gut durchdacht sein. Mit direkter Konstruktion (new Form()) fliegt Dir die Anwendung bald um die Ohren, weil Du den Überblick verlierst. DU bist für die Lebenszeit der Forms verantwortlich. Ich persönlich verwende eine eigene Basisklasse "MenuForm". Die kann sowohl als "Parent" als auch als "Child" einer verschachtelten Baumstruktur von Forms dienen. Alle Elemente in diese Baum können Nachrichten an Interfaces (diese können andere Forms sein) versenden, bei Wunsch Nachrichten abhören und Seitenwechsel veranlassen. Es gibt Events bei Verlassen (aber im Speicher halten) einer Form, beim Zerstören, beim Wiederbetreten. Damit kann ich ohne Probleme Anwendungen mit dutzenden Forms bauen ohne den Überblick zu verlieren. Ganz am Anfang habe ich auch ohne eine solche Verwaltung gearbeitet und bin schon bei 5 Forms gewaltig ins Schlingern geraten.

    3. Man koppelt so schwach wie möglich. Stichworte sind Dependency Injections, Interfaces und Events. Speziell Forms sollten sich gegenseitig garnicht kennen. Der Wechselseitige Zugriff auf die öffentlichen Parameter zweier Forms ist eine Todsünde. Globale Variablen oft auch.

    5. UserControls. Auch hier ist mehr zu tun als bei den Delphi-Komponenten.

    In C# ist wesentlich mehr Eigeninitiative und Handarbeit gefragt als in Delphi. Die Entwicklungszeit dürfte v.a. anfangs ein Vielfaches betragen. Die Denkweise ist eine andere. Ich würde Dir dringend empfehlen Grundlagenbücher zu lesen, auch wenn Dir das als altgedienter Entwickler vielleicht absurd vorkommen mag.

    Mach dich auf was gefasst 😉



  • Danke für die schnelle Antwort.

    µ schrieb:

    3. Man koppelt so schwach wie möglich. Stichworte sind Dependency Injections, Interfaces und Events. Speziell Forms sollten sich gegenseitig garnicht kennen. Der Wechselseitige Zugriff auf die öffentlichen Parameter zweier Forms ist eine Todsünde. Globale Variablen oft auch.

    Die Denkweise ist eine andere. Ich würde Dir dringend empfehlen Grundlagenbücher zu lesen, auch wenn Dir das als altgedienter Entwickler vielleicht absurd vorkommen mag.

    Mach dich auf was gefasst 😉

    Zu Punkt 3: Wenn das so sein sollte, wie kann man dann eine zweite Form als "Setup" nutzen, um später im Hauptformular z.B. auf Programmeinstellungen zuzugreifen?

    Tja, das kommt mir absolut nicht absurd vor. Ich schwite den ganzen Tag schon an einem Buch, welches ich auf galileocomputering gefunden habe.



  • Die Denkweise ist nicht unbedingt eine andere. Weil Delphi nicht ganz so streng ist, heißt es noch lange nicht, dass unsauberer Stil angebracht ist. So ziemlich jede deiner Fragen deutet auf mangelndes Verständnis hin, sorry wenn ich das so deutlich formuliere. Wie µ schon sagte, du solltest es erstmal paar Bücher lesen und wesentlich mehr Grundkenntnisse aufbauen, bevor du völlig uninteressante konkrete Fragen stellst.



  • TRM schrieb:

    Zu Punkt 3: Wenn das so sein sollte, wie kann man dann eine zweite Form als "Setup" nutzen, um später im Hauptformular z.B. auf Programmeinstellungen zuzugreifen?

    Mehrere Möglichkeiten:
    1. Du setzt ein Interface voraus das irgendwo im Programm implementiert sein muss, und fragst dies über ein DI-Container ab (Wie es konkret implementiert ist, ist dir dabei aber egal).
    2. Wenn das Hauptformular keine direkte Bindung braucht, beispielsweise wenn das Hauptfenster nur ein Container für beliebige andere Fenster und ein Hauptmenü ist, kann es auch sein das man ein Modul oder Pluginsystem verwendet, das sich in das Menü etc. einbettet (hierzu kann man sich auch das Prism-Framework anschauen [Nein, ich meine nicht Delphi Prism ;p]).

    TRM schrieb:

    Ich schwite den ganzen Tag schon an einem Buch, welches ich auf galileocomputering gefunden habe.

    Die Aussage von µ mit "Ich würde Dir dringend empfehlen Grundlagenbücher zu lesen..." halte ich bei seinen anderen Aussagen schon sehr problematisch, auch wenn es natürlich stimmt (Wobei mir bei Galileo eher Schüttelkrämpfe kommen, wobei dies in C# zum Glück nicht so schlimm ist wie in C++, wo ich dir sofort von den Büchern abraten würde). Gerade zu Themen wie "Dependency Injection" wurde ich in vielen Büchern nicht, oder nur eingeschränkt fündig. Und nur wenige Bücher verbinden wirklich sinnvoll mehrere Themen.

    Zu deinen ersten Fragen fehlte davon abgesehen noch die Frage ob du WinForms, WPF oder Silverligth etc. verwendest, da C# mehrere UI-Frameworks unterstützt (WinForms war bis einschließlich .NET 2.0 das Standardframework, ab 3.0 wurde dies eigentlich WPF, zudem gibt es z.B. die Silverlight-Entwicklung [Ähnelt WPF] und mit dem nächsten VS kommt dann noch das WinRT-Framework, das aber nur ab Windows 8 in der Metrooberfläche verwendung findet).

    Wie µ gehe ich mal davon aus das du (weil es in vielen Büchern als erstes angesprochen wird) WinForms verwendest. WPF ist an sich mächtiger, aber hat auch höhere Einstiegshürden (gerade von dem Denkansatz her, da es nur wenige vorgefertigte Controls gibt, diese aber beliebig verschachtelt werden können). So kennt WPF z.B. von Haus aus keinen Button der ein Bild und einen Text anzeigt, dies kann man aber durch eine Verschachtelung eines Buttons mit einem StackPanel, einem Image und einen TextBlock erreichen... (Im Endeffekt ist dies auf der einen Seite erst einmal Komplex, auf der anderen Seite ist dafür nahezu alles erdenkliche möglich, kombiniert mit einem mächtigen Bindingsystem).



  • Vielen Dank für eure Antworten. Ich lese noch eine Weile 🙂



  • TRM schrieb:

    2. In Delphi war ich gewohnt, dass ich Formularübergreifend arbeiten kann. So konnte ich z.B. einfach das Hauptformular verstecken und ein zweites anzeigen. Wenn das zweite nicht mehr benötigt wird, kann ich es schließen und das Hauptformular wieder anzeigen lassen.

    Ein solches Design würde ich als Anwender in den meisten Anwendungen ablehnen. Tendenziell sind eigentlich inzwischen Anwendungen üblich in dem mehrere Fenster gleichzeitig geöffnet sein können (Sei es nun in dem tendenziell als veraltet geltenden MDI-Stil, sei es mit eingebetteten Tabs...). Unsere Kunden haben uns jeden Schritt weg von rein modalen Fenstern gedankt (am liebsten mit der Möglichkeit mehrere Fenster auch parallel unabhängig von einander offen zu haben, z.B. um auch Daten vergleichen zu können).

    TRM schrieb:

    3. Wie regelt man in VC# die Formularübergreifenden Constanten/Variablen/Klassen?

    Dies ist auch unter Delphi ein schlechter Stil, und sollte zumindest weitgehend vermieden werden (es mag Ausnahmen geben, die Regel sollte dies aber nicht sein).

    TRM schrieb:

    Ein schönes Tutorial zum MS SQL Server als Embedded DB habe ich gefunden. Gibt es in VC# Express nur wenige visuelle Datenobjekte?

    Was die Anzahl angeht mag das kostenlose VC# Express nicht mit einem kostenpflichtigen Delphi konkurrieren können, es gibt aber inzwischen weit mehr Komponentenhersteller sowie kostenlose Komponenten für VC# als für die VCL. Und je nach Framework sagt die Anzahl der Komponenten nicht unbedingt viel aus.

    TRM schrieb:

    Ist es mir möglich unter VC# 2010 so genannte eigene Komponenten zu erstellen, welche dann auf eine Form gepackt werden können - sichtbar und unsichtbar - und wenn ja, gibt es hierzu bitte ein Tutorial?

    Prinzipiell ja, wobei ich zu Büchern raten würde. Und spätestens hier wäre es ganz wichtig das Framework zu wissen, da es massive unterschiede zwischen WinForms auf der einen, und den XAML-basierten Frameworks (WPF/SL/WinRT) auf der anderen Seite gibt.



  • asc schrieb:

    Die Aussage von µ mit "Ich würde Dir dringend empfehlen Grundlagenbücher zu lesen..." halte ich bei seinen anderen Aussagen schon sehr problematisch, auch wenn es natürlich stimmt

    Was meinst Du damit?



  • asc schrieb:

    Mehrere Möglichkeiten:
    1. Du setzt ein Interface voraus das irgendwo im Programm implementiert sein muss, und fragst dies über ein DI-Container ab (Wie es konkret implementiert ist, ist dir dabei aber egal).

    Zu deinen ersten Fragen fehlte davon abgesehen noch die Frage ob du WinForms [..]

    Ich nochmal,

    wäre es denn ein großer Aufwand, wenn Du mir zum Punkt 1 ein kleines Beispiel zeigen könntest, wie Du das mit eienr Hauptform und einer zweiten Form zeigst, wobei die Hauptform auf eine CheckBox von Form2 zugreift ?

    Am Anfang würde ich wohl wirklich erst einmal WinForms verwenden, da dies der typischen Gestaltung am nächsten kommt, die ich gewohnt bin.

    Viele Grüße
    Mathias



  • TRM schrieb:

    wäre es denn ein großer Aufwand, wenn Du mir zum Punkt 1 ein kleines Beispiel zeigen könntest, wie Du das mit eienr Hauptform und einer zweiten Form zeigst, wobei die Hauptform auf eine CheckBox von Form2 zugreift ?

    Es wurde schonmal gesagt: Man greift nicht direkt auf Controls von anderen Forms zu.

    Die Forms kommunizieren über, an die jeweiligen Konstruktoren übergebene, Objekte. Die Klassen dieser Objekte implementieren ein Interface, häufig mit Events. Das Ziel ist, die Kopplung so weit es geht zu minimieren.

    Deshalb habe ich Grundlagenbücher empfohlen. Das ist unabhängig von Forms eine gute Vorgehensweise in C#.

    Beispiellernen halte ich für nicht angebracht.



  • µ schrieb:

    asc schrieb:

    Die Aussage von µ mit "Ich würde Dir dringend empfehlen Grundlagenbücher zu lesen..." halte ich bei seinen anderen Aussagen schon sehr problematisch, auch wenn es natürlich stimmt

    Was meinst Du damit?

    Grundlagenbücher zu lesen ist sinnvoll, die Themen die du angesprochen hat (u.a. DI) werden aber häufig in solchen nicht behandelt. Daher reicht es nicht nur allgemein auf Grundlagenbücher zu verweisen, wenn man schon weiterführende Themen nennt (Oder nenn bitte ein Grundlagenbuch, das diese Themen auch beinhaltet).

    Das der Threadstarter aber mit Grundlagenbüchern beginnen sollte würde ich auch unterstreichen, ebenso wie er seine bisherigen Designansätze überdenken sollte (Alles was er aktuell schreibt ist unter keiner Sprache guter Stil).

    Nachtrag: Zum Thema DI verweise ich mal auf die folgende Einführung.



  • µ schrieb:

    Deshalb habe ich Grundlagenbücher empfohlen. Das ist unabhängig von Forms eine gute Vorgehensweise in C#.

    Beispiellernen halte ich für nicht angebracht.

    Bücher sollten die erste Quelle sein, aber einzelne Beispiele um ihm aufzuzeigen was er bisher schon immer falsch gemacht hat, wären aber auch nicht verkehrt. Nicht jeder Mensch kann mit einer rein theoretischen Beschreibung lernen (Ich z.B. lerne am besten wenn ich einerseits die Theorie lerne, anderseits aber auch kleine Praxisbeispiele sehe).

    Wenn meine Frage nach dem UI-Framework mal beantwortet werden würde, könnte ich entscheiden ob ich (nach ein paar Detailfragen) ein kurzes Beispiel mache. Nur ist mein .NET-Wissen lückenhaft, da ich Themen auslasse, die ich nicht benötige (z.B. habe ich WinForms von vorne herein ausgeklammert - so das ich sicherlich hier kein Beispiel schreiben kann).

    Das Problem an rein Büchern ist: Man hat meist viele Interpretierungsmöglichkeiten, und selten bekommt man mehr als allgemeine Hilfestellungen wenn es komplexer wird. Nur wenige Bücher zeigen mögliche Designfehler auf, und stellen saubere Lösungen dem gegenüber. Vor einem ähnlichen Problem stehe ich derzeit: Ich glaube zwar ein grundsätzliches Verständnis von DI, Prism usw. zu haben, bin mir aber an vielen Stellen noch unsicher, und suche mich um mal Beispiele zu finden die ungefähr auf meine Problemstellung passen einen Wolf.

    Gerade weil ich eine saubere Migration machen will, stell ich mir häufig die Frage: Ist der Ansatz den ich hier habe wirklich der richtige? Gibt es vielleicht bessere Möglichkeiten?
    Ich migriere nicht einen seit 10 Jahre gepflegten Code um anschließend fest zu stellen, das meine Migration schlecht ist.



  • Hallo TRM,

    evtl. hilft dir ja mein Artikel Kommunikation von 2 Forms weiter (aber eigentlich - so wie µ und asc schon geschrieben haben, sollte man auch schon in Delphi entsprechend programmiert haben 😉
    Ganz unten habe ich auch ein WinForms-Beispielprogramm (als ZIP-Datei) angehängt, welches die Benutzung von Eigenschaften und Ereignissen in der Praxis zeigt.



  • Th69 schrieb:

    Hallo TRM,

    evtl. hilft dir ja mein Artikel Kommunikation von 2 Forms weiter (aber eigentlich - so wie µ und asc schon geschrieben haben, sollte man auch schon in Delphi entsprechend programmiert haben 😉
    Ganz unten habe ich auch ein WinForms-Beispielprogramm (als ZIP-Datei) angehängt, welches die Benutzung von Eigenschaften und Ereignissen in der Praxis zeigt.

    Danke für den Artikel.

    Das, was Du mir damit gezeigt hast, habe ich nun (hoffentlich) verstanden. Was mir aber nicht in den Kopf gehen will ist die Tatsache, dass mit diesem Verfahren der zu schreibende Code mehr als doppelt so groß wird.

    Als Beispiel möchte ich bitte das Einstellungsfenster (Form2) hernehmen. Wenn dies geöffnet wird, sollen Werte anpassbar sein, welche später in Form1 (Hauptform) abrufbar sind.

    Dein Code aus dem Beispiel hierzu:

    private void menuItemSettings_Click(object sender, EventArgs e)
    		{
    			SettingsDialog settingsDlg = new SettingsDialog();
    			settingsDlg.BackgroundColor = BackColor;
    			settingsDlg.CurrentFont = Font;
    			settingsDlg.SettingsChanged += settingsDlg_SettingsChanged;
    
    			if (settingsDlg.ShowDialog(this) == DialogResult.OK)
    			{
    				BackColor = settingsDlg.BackgroundColor;
    				Font = settingsDlg.CurrentFont;
    			}
    		}
    

    Angenommen in Form2 sind 40 Checkboxen, die alle zu späteren Zeitpunkten evtl. abgefragt werden müssen. Somit müsste ich in jedem (?) Prozedureabschnitt, welcher Zugriff auf ein oder mehrere der Checkboxen benötigt, die Form2 deklarieren, um die Werte abrufen?

    Das Beispiel sähe dann dazu so aus (?):

    private void menuItemSettings_Click(object sender, EventArgs e)
    		{
    		 bool chkBox1;
    		 bool chkBox2;
    		 bool chkBox3;
    //		 [weitere boolean deklarieren]
    		 bool chkBox39;
    		 bool chkBox40;
    
    			SettingsDialog settingsDlg = new SettingsDialog();
    			settingsDlg.SettingsChanged += settingsDlg_SettingsChanged;
    
    			if (settingsDlg.ShowDialog(this) == DialogResult.OK)
    			{
           chkBox1 = settingsDlg.CheckBox1.Checked;
           chkBox2 = settingsDlg.CheckBox2.Checked;
           chkBox3 = settingsDlg.CheckBox3.Checked;
    //       [weitere Zuweisungen]
           chkBox39 = settingsDlg.CheckBox39.Checked;
           chkBox40 = settingsDlg.CheckBox40.Checked;
    }
    		}
    
    private void button1_Click(object sender, EventArgs e)
    		{
    		 bool chkBox1;
    		 bool chkBox2;
    		 bool chkBox3;
    //		 [weitere boolean deklarieren]
    		 bool chkBox39;
    		 bool chkBox40;
    
    			SettingsDialog settingsDlg = new SettingsDialog();
           chkBox1 = settingsDlg.CheckBox1.Checked;
           chkBox2 = settingsDlg.CheckBox2.Checked;
           chkBox3 = settingsDlg.CheckBox3.Checked;
    //       [weitere Zuweisungen]
           chkBox39 = settingsDlg.CheckBox39.Checked;
           chkBox40 = settingsDlg.CheckBox40.Checked;
    		}
    

    In Delphi hatte ich mir dafür einfach eine eigene Function geschrieben, mit welcher ich einen globalen Typ gefüllt hatte. Somit konnte dieser Typ aus einer einzigen Funktion initialisiert werden, was den Programmieraufwand um ein vielfaches verkleinerte, da es nur eine Stelle gab, in der dies passierte. Des Weiteren war diese Function dann in einer extra Unit ausgelagert, welche in entsprechend in anderen Units (Form1, Form2 oder in Units ohne Form) einbinden konnte.

    Ich bitte den geneigten Leser meines Beitrages nicht mich zu verteufeln, wie ich bisher meinen Programmierstil ausgeübt habe, ich bin ein Autodidakt, wie viele andere auch. Ich möchte gern dazu lernen, jedoch entschließt sich die Argumentation bzw. der Sinn hinter dem von euch angesprochenen Verfahren für mich nicht.

    Als Abschluß ein Beispiel, wie ich es bisher in Delphi gehandhabt habe:

    // Dieser Abschnitt erstellt einen eigenen Typ, welcher schnell anpassbar ist. Der Typ muss für alle Units verfügbar sein, die die function weiter unten nutzen möchten.
    type
      TActual_User = record
        User_Number: boolean;
        User_Name: boolean;
        User_Vorname: boolean;
        User_Username: boolean;
        User_TimeOut: boolean;
    // [weitere Werte]
        User_TimeOut_Timer: boolean;
        User_TimeOutSystem: Boolean;
      end;
    
    //Diese Funtion ist die Schnittstelle zu einer "Setupform", auf der mehrere Checkboxen liegen. Ausgelagert in eine eigene Unit kann diese unit z.B. in der Hauptform eingebunden werden (uses Unit_setup;). Damit diese Function Zugriff auf die Setupform hat, muss die Setupform sichtbar gemacht werden (uses setupunit;). Dadurch ist es der Function möglich direkt auf die Elemente der Form zuzugreifen und in diesem Fall auszulesen.
    function readCheckBoxes(var Ergebnis:TActual_User):Boolean;
    begin
     result:=false;
     try
      Ergebnis.User_Number := Setupform.Checkbox1.checked;
      Ergebnis.User_Name := Setupform.Checkbox2.checked;
    //[weitere Werte]
      Ergebnis.User_TimeOutSystem := Setupform.Checkbox40.checked;
      result:=true;
     except
     end; 
    end;
    
    //Diese Funktion ruft die Schnittstelle auf und erhält eine Variable zurück
    procedure button1click(sender:tobject);
    var
      Actual_User: TActual_User;
    begin
        if readCheckBoxes(Actual_User) then
        begin
         showmessage('Auslesen war erfolgreich, Werte sind in Actual_User gespeichert.');
    
    //Nutzbar sind die Checkboxwerte nun über die Variable Actual_User
         if Actual_User.User_Number then showmessage('User_Number ist gesetzt.');   
         if Actual_User.User_Name then showmessage('User_Name ist gesetzt.');
    //  [weitere Werte]
         if Actual_User.User_TimeOutSystem then showmessage('User_TimeOutSystem ist gesetzt.');
        end;
    end;
    


  • Hallo TRM,

    du kannst selbstverständlich auch Eigenschaften mit eigenen Typen erstellen (für deinen Fall wäre entweder ein reine Datenklasse (bzw. -Struktur) oder sogar ein Array geeignet):

    class Data
    {
      public bool Value1 { get; set; }
      public bool Value2 { get; set; }
    }
    

    Wichtig ist jedoch, daß diese Datenklasse entweder in der gleichen Datei wie die Settings-Klasse oder aber in einer unabhängigen Datei gespeichert wird (nicht jedoch in der aufrufenden Forms-Klasse - da sonst eine Kreuzabhängigkeit entsteht!).

    Und dann kannst du diese Klasse als Eigenschaft der Settings-Klasse benutzen:

    public Data MyData
    {
      get
      {
         Data data = new Data();
    
         data.Value1 = checkBox1.Checked;
         data.Value2 = checkBox2.Checked;
    
         return data;
      }
    }
    

    (wichtig ist ja nur, daß nicht direkt von außen auf interne Controls zugegriffen wird).
    So wie du es bisher also in Delphi gemacht hast, war also schon fast richtig (einzig der Zugriff von außen auf die globale 'Setupform'-Variable ist ein "NoGo" - diese Methode gehört in die Settings-Klasse).

    Daß Delphi (bzw. auch der C++ Builder) immer diese globalen Form-Variablen angelegt hat, hat gerade für viele Anfänger das Verständnis für objektorientierte Programmierung behindert (daher habe ich die Forms immer selber angelegt - über Member- bzw. sogar lokale Variablen, so wie es sich im OOP-Sinne gehört).

    Testen kann man die Unabhängigkeit am besten immer an einem neuen leeren Projekt - dort dann einfach z.B. die Settings-Klasse hinzufügen (+ evtl. Datenklassen oder Utility-Klassen) und wenn es dann ohne Fehler kompiliert, hat man es (bisher) richtig gemacht.



  • Th69 schrieb:

    Und dann kannst du diese Klasse als Eigenschaft der Settings-Klasse benutzen
    [..]
    (wichtig ist ja nur, daß nicht direkt von außen auf interne Controls zugegriffen wird).

    Vielen Dank für die Erläuterung. Damit ich es richtig verstehe:

    public Data MyData wird im Codecontext der "Setupform" ausgeführt, nicht ausgelagert?

    Wenn das so ist, muss ich dann aus einer anderen Form-Unit diese Function aufrufen und gleichzeitig die "Setupform-Unit" sichtbar machen für diese andere Form-Unit?



  • Ja, exakt.



  • Danke an alle Helfer.

    Dieser Thread kann von meiner Seite aus geschlossen werden.

    Ein schönes Osterfest 🙂


Anmelden zum Antworten