Wie Funktion der übergeordneten Klasse aufrufen? EDIT: Frage zu TabControlOhneReiter

  • VB.NET

Es gibt 66 Antworten in diesem Thema. Der letzte Beitrag () ist von sonne75.

    Wie Funktion der übergeordneten Klasse aufrufen? EDIT: Frage zu TabControlOhneReiter

    Hallo, ich habe schon wieder eine Frage:

    ich habe eine Hauptform und da drin ein TreeView und eine Klasse XX, die mehrere Panels enthält. Diese Panels werden abhängig von der Auswahl im TreeView geladen. Zuerst will ich nur ein Panel anzeigen und nur ein Eintrag im TreeView haben. Wenn da die Eingaben stattfinden, sollen die anderen Nodes im TreeView hinzugefügt werden und dadurch andere Panels (abhängig von Eingaben im ersten Panel) geladen werden.
    Die Frage ist, wie gelangt die Information über die erfolgte Angaben im Panel (eine Klasse innerhalb der Klasse XX) in diese Klasse XX, damit ich da die Funktion "ChangeTreeView" aufrufen kann? Die Angaben darüber, welche Panels geladen werden sollen, würde ich in jeweiligen Boolean-Variablen speichern. In welcher Klasse sollten sie dann Member sein? Im ersten Panel oder in der Klasse XX? Wenn XX, wie kann sie sie dann verändern? Dieses Panel enthält ja die Klasse XX nicht, sondern umgekehrt, es ist ein Teil der Klasse XX und kann doch auf die Variablen und Funktionen der Klasse XX nicht zugreifen oder?

    Ich hoffe, ich konnte es verständlich rüberbringen.

    LG Sonne

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „sonne75“ ()

    Danke für deine Antwort. Very Basics habe ich schon gelesen, daher wusste ich, dass ich nicht so einfach auf die übergeordnete Klasse zugreifen kann. Ich wusste auch über Events, nur kann man kein Event auf eine Variable machen und extra eine Klasse für diese Variable nur um ein Event aufrufen zu können - muss es wirklich so kompliziert sein?

    Die Geschichte mit Tabcontrols ist auch interessant, nur ist es in diesem Projekt schon so umgesetzt, dass die Panels erzeugt werden und je nach Item angedockt werden: ich möchte an der Grundstruktur des Projekts nicht so viel ändern.

    Daher die Frage: kann ich ein Event aufrufen ohne eine Klasse für diese Variable zu machen (und bei Properties RaiseEvent bei Set aufzurufen)?

    LG
    Ich habe jetzt noch mal aufgezeichnet. Das mit der Variable in der Klasse verstehe ich immer noch nicht, denn wo soll das Objekt dieser Klasse dann erzeugt werden? Wenn ich dieses Objekt in der Klasse XX (Klasse Device auf dem Bild) anlege, wo ich zumindest über die Form auf das TreeView zugreifen kann (ist es eigentlich auch falsch? So hat der Entwickler es bisher immer gemacht), dann muss ich ja noch ein Objekt davon in der Panelklasse erzeugen. Wenn ich aber RaiseEvent da auslöse, hat es doch keine Auswirkungen auf das Objekt in der übergeordneten Klasse, oder? Es sind zwei Objekte derselben Klasse, wie ich das verstehe.

    Irgendwie fehlt mir noch das Verständnis dafür, ich habe bisher nie was damit zu tun gehabt...

    ich blick da nicht ganz durch, und insbesondere verdächtig ist mir, dass die Device-Klasse Panels enthält. Hier vermischen sich Daten und Oberfläche, unds wird total komisch.
    Panels gehören aufs Form, weil nur ein Form kann ein Panel anzeigen.

    Ich würde das datenmodellmäßig sehen, also du hast ein Daten-Objekt "Device", und das enthält eine Liste von anneren DatenObjekten, für die du offenbar bislang noch gar keine Bezeichnung hast (weil "Panel" ist ja kein Datenobjekt).
    Und dein Problem ist, dieses Device-Objekt mit allen UnterObjekten auf 2 verschiedene Weisen anzuzeigen, einmal im Treeview, und zum anneren auf Panels (also am einfachsten im TabControl).
    Ich würde sicher malwieder die Geschichte im typisierten Dataset modellieren - die DatenObjekte, die da generiert werden schmeißen reichlich genug Events, um einen multiplen View damit zu steuern.
    Also das Form würde über BindingSources oder noch schlimmeres allerlei Events aus dem Dataset empfangen, und dementsprechend sowohl im Treeview als auch im TabControl herumfuhrwerken.

    Wassich immer sage: Datenverarbeitung programmieren fängt mit dem Datenmodell an, und da fehlt mir jetzt annähernd jede Info, um was für Daten es sich eiglich handelt.
    Ich habe nochmal nachgeschaut: diese "Panelklasse" ist von System.Windows.Forms.UserControl abgeleitet, ich nehme also an, es ist eine Form. Es gibt auch einen Designer dafür, wo die ganzen Steuerelemente definiert werden usw.
    Am Anfang vom Programm werden alle diese "Panels" zu der Mainform addiert

    VB.NET-Quellcode

    1. frmMain.SplitContainer1.Panel2.Controls.Add(uctlButtons1)
    , uctlButtons1 ist in dem Fall so eine Panelklasse. Diese Klassen braucht man für die XML-Serialisierung, weil die ganzen Einstellungen in XML gespeichert werden. Noch dazu habe ich dann Sprachdateien, die die Texte der Controls festlegen (in jeder Panelklasse einzeln).
    Nach Auswahl eines TreeView-Knotens wird dieses zugehörige Panel angedockt:

    VB.NET-Quellcode

    1. HideControls() 'da werden alle Panels auf Unvisible gesetzt (uctlButtons1.Visible=False usw)
    2. uctlCommon1.Visible = True
    3. uctlCommon1.Dock = DockStyle.Fill


    Ich nehme also an, das ist auch je eine Form, die in der Hauptform angedockt und dann nur jeweils eine gezeigt wird.

    Dieses Programm hat ein erfahrener Programmierer geschrieben, er verwendet dieses Modell wohl in vielen Projekten. Leider hat er meine Aufgabenstellung (Einträge im TreeView verstecken und anzeigen, je nach Panelangaben) nicht gehabt, sonst könnte ich es da abschauen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „sonne75“ ()

    Was gefällt dir denn daran genau nicht? Ich fand das Modell sehr nachvollziehbar, habe wenige Tage gebraucht um hinter ganzes System (da ist noch einiges dabei) durchzusteigen und zu verstehen, was ich davon für mein Projekt verwenden kann und was nicht. Aber natürlich habe ich sehr sehr wenig Erfahrung mit OOP, ich komme von C und LabView, da entstehen solche Probleme nicht mal.

    EDIT: Was ist der Vorteil deiner Methode der unsichtbaren TabControls, außer dass man da einfach auf das TreeView (das bräuchte ich ja immer noch um zu entscheiden, welches TabControl gerade angezeigt wird, oder?) zugreifen kann?

    EDIT2: Zu deiner Frage: es gibt eine Klasse (XX-Device), da ist ein Objekt der Klasse "Alle Parameter" implementiert. "Alle Parameter" besteht aus einzelnen Klassen für je Panel mit Parametern, das Ganze wird für XML-Serialisierung benötigt (Einstellungen speichern und lesen). Und dann sind in dieser XX-Device-Klasse noch die einzelnen Formen/Panels als Objekt deklariert (?? mit New auf jeden Fall erzeugt). Alle Datenmanipulationen bzgl. Panelsteuerelemente (und auch Visible oder nicht für einzelnen Panels) werden hier aufgerufen (über Objektinstanzen einzelnen Panelklassen).
    Auf die Mainform wird nur zugegriffen um die Panels anzudocken und um auf TreeView zuzugreifen.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „sonne75“ ()

    naja - für Daten gibts fabelhafte Datenklassen, bei denen alle Probleme von Laden, Speichern, Editieren, Sortieren, Filtern, Zufügen, Löschen ein für allemal gelöst sind, und die obendrein noch Databinding unterstützen.
    Da macht man keine Übungen mit Xml, mit denen man möglicherweise in einer anneren Kultur auch noch böse auf Nase fallen kann.

    Aber das ist jetzt wohl egal - was man dir da vorsetzt wirst du wohl nicht neu und richtig aufziehen dürfen.

    Aber ich weiß jetzt nicht das Problem mit den Variablen, die ein Event senden sollen: Du kannst den UserControls doch Events verpassen, und das Form reagiert dann drauf.

    ErfinderDesRades schrieb:

    Aber das ist jetzt wohl egal - was man dir da vorsetzt wirst du wohl nicht neu und richtig aufziehen dürfen.
    Das dürfte ich sogar. Ich soll dieses Projekt als Basis nehmen, bin aber nicht gezwungen dazu (bzw. ich soll das Aussehen als Basis nehmen; mit deinen TabControls würde es ja genau so aussehen). Die alten Projekte betreuuen muss ich trotzdem.
    Bisher habe ich nicht verstanden, was an diesem Modell so schlecht sein soll, immerhin ist es fertig und ich verstehe, wie es funktioniert.
    Mit
    naja - für Daten gibts fabelhafte Datenklassen, bei denen alle Probleme
    von Laden, Speichern, Editieren, Sortieren, Filtern, Zufügen, Löschen
    ein für allemal gelöst sind, und die obendrein noch Databinding
    unterstützen.
    kann ich leider nicht viel anfangen, weil ich absolut nicht weiss, was du meinst.

    Würde ich ein anderes (in deinen Augen besseres) Modell verstehen, wie es aufgebaut ist, würde ich es verwenden dürfen.


    ErfinderDesRades schrieb:

    Aber ich weiß jetzt nicht das Problem mit den Variablen, die ein Event senden sollen: Du kannst den UserControls doch Events verpassen, und das Form reagiert dann drauf.
    Ja, ich habe Events von UserControls, aber in dieser untergeordneten "Panelklasse". Da kann ich was reinschreiben, was mit TreeView-Einträgen passieren soll. Nur, wie komme ich an diese Einträge ran, wenn sie in einer 2 Klassen höheren Klasse drin sind?

    EDIT: Ich lese mir gerade dein "Alles über Events" durch, vielleicht finde ich die Lösung, dann sage ich Bescheid.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „sonne75“ ()

    ErfinderDesRades schrieb:

    sonne75 schrieb:

    Nur, wie komme ich an diese Einträge ran, wenn sie in einer 2 Klassen höheren Klasse drin sind?
    Wieso 2 Ebenen höher?
    Das UserControl sitzt doch auffm Form, und der Treeview ebenso.
    Oder ist das der Punkt wo iwie dieses Device-Dingens zwischengefrickelt ist?
    Die Usercontrols sitzen jeweils in den "Panelklassen", z.b. uctlButtons1. Objekte dieser Klasse sind alle in der Klasse "XX-Device" instanziert (und das Objekt dieser Device-Klasse ist in der Mainform instanziert), da passieren alle Datenmanipulationen (jeweilige Funktionen dieser Objekte werden da aufgerufen, z.B. uctlButtons1.SetType()).
    also wirklich verwarzt.
    UserControls, Panelklassen (die aber scheinbar keine Panels sind), und auch noch XX-Device-Klassen - gibts da auch noch XY-Device-Klassen?
    Klingt, als könne man Daten und Oberfläche nicht schlimmer zusammenrühren und zu Mansche kochen.

    kann ich leider nicht viel anfangen, weil ich absolut nicht weiss, was du meinst.

    Würde ich ein anderes (in deinen Augen besseres) Modell verstehen, wie es aufgebaut ist, würde ich es verwenden dürfen.
    datenmodell-getriebene Anwendungs-Entwicklung beruht auf einigen wesentlichen Grundkonzepten. Die sind eiglich nicht weiter kompliziert, imo haperts bei vielen daran, die Konzepte auch konsequent für sich arbeiten zu lassen.

    Man muß halt den Kopf wirklich wegkriegen von den Steuerelementen, und hinwenden zu den tatsächlichen Verhältnissen, die zu modellieren sind.
    Also in deinem Fall weg von Treeview und UserControl und Panel, und hin zu diesen Device-Dingern und seinen untergeordneten Daten, für die du ja bislang noch nichtmal ein Wort hast.

    Manche Leuts nicken die Theorie nur ab, und setzen sie gleich um, annere kriegens über Jahre nicht wirklich in den Kopf. Aber als Programmierer gibts in meinen Augen eiglich keine Alternative dazu, in diese Thematik iwann mal einzusteigen.

    also zunächstmal ist die relationale GrundIdee zu schnackeln, und zu begreifen, dass mit dem relationalen Modell wirklich ein Ansatz gefunden ist, mit dem man alles modellieren kann, was man in irgendeiner Weise als Ding auffassen kann, ob das nun Pferde sind, oder Verträge oder Vertragsbrüche.

    guck dirmal diese Pferde-Geschichte an, vlt. wird da ein bischen plastisch, wie realitätsnah, und scheinbar computerfern diese Denkweise ist. Tatsächlich ist die Denkweise durchaus computer-nah, denn wenn ich sag "Es gibt mehrere Pferde, und mehrere Tierärzte, und jedes Pferd hat einen Tierarzt", dann ist damit im Grunde bereits festgelegt: "Ein Datensatz der Pferd-Tabelle verweist auf einen übergeordneten Datensatz der Tierarzt-Tabelle", und letzteres kann man direkt im DatasetDesigner zurecht-klicksen.
    Eins vorab, ich glaube, wir reden über unterschiedliche Dinge. Ich werde deine Links auf jeden Fall durchlesen, aber ich habe jetzt gesehen, dass ich es einfach falsch beschrieben habe.

    Also, es gibt ein Gerät und das Programm, was ich schreibe, ist seine Konfigurationssoftware. Da werden verschiedene Parameter ausgewählt und gesetzt und am Ende diese Daten per USB an das Gerät übermittelt (das ist kein Problem, das kriege ich hin).
    Da es viele Parametergruppen gibt, werden diese Parameter gebündelt je in einerm "Tab"/Panel angezeigt. Wie dieser Tab zustande kommt, ob durch Tabcontrol oder sichtbare Formenteile, ist erst mal egal.
    Je nachdem, was im ersten Tab/Panel ausgewählt wurde, muss man andere Parametergruppen zuschalten oder nicht. Da kommt mein Problem: wie komme ich auf das TreeView ran um Einträge hinzuzufügen?
    Hmm - jetzt scheints wieder nur um einen einzigen Datensatz zu gehen, nämlich um eine Konfiguration. Und da gibts so viel dran einzustellen, dass alles auf ein Form gebatscht erschlagend würkte.
    Vermutlich gibts aber auch allerlei Listen, aus denen was auszuwählen wäre - sowas wäre gleich wieder ein Grund, um wieder mit Dataset anzufange.

    Jedenfalls im Grunde nur ein Datensatz, der von vornherein vollständig vorhanden ist, aber nur schrittweise zum editieren sichtbar gemacht werden soll.
    Ist das nicht ziemlich genau das, was in TabControlOhneReiter unter "Assistenten-Navigation" vorgeführt ist?
    Meinetwegen parallel dazu eine "Frameset-Navigation", und besonderer Aufwand ist wohl zu treiben, die beiden Navigationen miteinander zu synchronisieren.

    Wos ums speichern geht, denke ich natürlich gleich daran, ein Datenmodell für mehrere solcher Datensätze zu schaffen, dann kann man sich auch die eine oder annere Konfiguration vorgefertigt auswählen und so Zeugs. Weil typDataset kann keine einzelnen Datensätze anlegen, da legt man halt immer eine Tabelle für Datensätze an.

    Also soll das Proggi nur eine Konfiguration bearbeiten, oder soll auch zw. verschiedenen Konfigurationen herumzuswitchen möglich sein?
    Bei diesem Programm sind es ca. 15-20 Controls (meistens Comboboxen mit 2-10 Einträgen, aus denen man auswählt). Die gleiche Struktur soll aber für alle zukünftige Konfigurationsprogramme verwendet werden und da können es möglicherweise 100-150 Controls geben.
    Dann wird aus diesen Einträgen ein Statuswort (aus mehreren Bytes) zusammengestellt und per USB ans Gerät geschickt.

    Voreingestellte Konfigurationen stehen nicht im Programm, der Kunde soll alles flexibel auswählen können (was er darf natürlich). Im XML gespeichert werden bei Comboboxen nur die SelectedIndex-Einträge oder direkte Zahlen (bei NumericUpDown), wie ich mitgekriegt habe.

    Ja, dein TabControlReiter macht genau das, aber mein Basisprogramm ja auch. Ich werde dein Beispiel nochmal genau ansehen, bisher scheint der Vorteil darin zu liegen, dass ich gut an das TreeView rankomme, weil alles in der gleichen Form liegt.
    Ich habe mir jetzt das "TabControlOhneReiter" angeschaut. Leider brauche ich ein TreeView statt einer Listbox (weil es in anderen Projekten sein kann, dass man Unterauswahl (Sensor->Sensor1, Sensor2, Sensor3) haben muss). Da gibt es weder Display-Member-Eigenschaft noch DataSource.
    Wie kann man dann die Datenbindung lösen?
    tja, dassis Pech. Treeview unterstützt nicht Databinding, daher musste dafür wesentlich mehr Aufwand treiben, um Aussehen und Verhalten der Treenodes mit den Tabpages zu synchronisieren.


    Ich weiß jetzt nicht, wie unterschiedlich die Geräte sind, weil vlt. kann man einen eigenen Xml-Dialekt schaffen, der sowohl den Aufbau des Guis beschreibt als auch die Daten der Konfiguration.

    Und dann muss ein Xml->Gui - Konverter her, ein Gui-Xml-Konverter, und ein Xml->KonfigurationsDaten - Konverter.

    Also halt Datenmodellierung in Xml :(

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Kann man es vielleicht doch mit einer ListView dann lösen?

    Z.B.

    Quellcode

    1. Tasten
    2. Lüftung
    3. Sensor
    4. Sensor1
    5. Sensor2
    6. Licht


    Also einfach paar Leerzeichen davor setzen? Es geht ja nur um die Anzeige, denke ich... Wie ich verstehe, werden die Texte für die ListView vom Text der jeweiligen TabPages übernommen, und da die Reiter nicht sichtbar sind, ist es doch egal, ob da ein paar Leerzeichen mehr davor stehen.

    EDIT: jetzt hat er mir tatsächlich meine Leerzeichen am Anfang entfernt, habe es jetzt als Code eingeführt
    Listview ist ein Schrott-Control - Der ListView-Holzweg
    jedenfalls die Tabellen-Ansicht ist in jeder Hinsicht vollkommen überholt durch DatagridView.

    Ja, wenn du die Nodes nicht zusammenklappen musst, dann kann man ein eingerücktes Zeichnen im DGV implementieren, und da gibts auch die Möglichkeit, im typisierten Dataset so Baumstrukturen zu modellieren - das wäre eine Möglichkeit, die Datenmodellierung in Xml sich zu ersparen.
    Also zusammenklappen kann DGV nicht, aber es sind listenreiche Filter denkbar, mit denen sich Zeilen ausblenden lassen.

    Dann braucht man nurnoch den Dataset->Konfiguration Konverter.
    Mit Konfiguration meine ich iwie einen Stream oder ein Byte-Array oder whatever, was dann letztlich ans Gerät geschickt wird.