Ein dynamsiches DataGridView innerhalb eines TabControls

  • VB.NET

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von blubberbaum.

    Ein dynamsiches DataGridView innerhalb eines TabControls

    Hallo zusammen,
    mit Hilfe Eurer Beiträge hab ich es geschafft ein Datagridview zur Laufzeit zu erzeugen und dies in ein Tabcontrol einzubinden.

    VB.NET-Quellcode

    1. Private Sub Button_Create_Click(sender As System.Object, e As System.EventArgs) Handles Button_Create.Click
    2. Dim DGV As New DataGridView
    3. With DGV
    4. .EditMode = DataGridViewEditMode.EditProgrammatically 'manuelles hinzufügen deaktivieren
    5. .ReadOnly = True
    6. .AllowUserToAddRows = False
    7. .Columns.Add("position", "Position")
    8. .Columns.Add("datum", "Datum")
    9. .Columns.Add("betrag", "Betrag")
    10. .Columns.Add("belegnummer", "Belegnummer")
    11. .Columns.Add("rechungsnummer", "Rechnungsnummer")
    12. End With
    13. Dim KTO As Integer
    14. KTO = InputBox("Text", "Überschrift")
    15. Dim TabIndex As Integer 'Anzahl der erstellten Tabs, bei keinem Tab ist der Index 0
    16. TabIndex = TabControl1.TabCount
    17. TabControl1.TabPages.Add(KTO)
    18. TabControl1.TabPages(TabIndex).Controls.Add(DGV)
    19. End Sub

    Mein Problem ist jetzt: Wie kann ich darauf zugreifen um Zeilen hinzufügen oder mit den Werten innerhalb des DGV zu arbeiten. Das normale DGV.Rows.Add() funktioniert nicht da er DGV ja nicht findet.
    Grüße
    @tomso: Präzisierung:

    VB.NET-Quellcode

    1. Private DGV As New DataGridView

    -----
    Was ist

    blubberbaum schrieb:

    InputBox
    :?: :D
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo,
    zunächst zu der Frage:

    RodFromGermany schrieb:



    Was ist

    blubberbaum schrieb:

    InputBox
    :?: :D

    Es ist eine von VB bereitgestellte Eingabebox. In meinem Fall sollen einmal verschieden Konten verwaltet werden können und diese Box im speziellen dient dann zum anlegen eines neuen Kontos und der Nutzer gibt dann einen Namen bzw die Nummer ein. Diese wird dann an die Variable KTO gebunden.


    Der oben genannte Lösungsvorschlag ist allerdings nicht erfolgreich. Dim DGV as New Datagridview als globale Variable zu definieren führt dann bei

    VB.NET-Quellcode

    1. Private Sub Test(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    2. DGV.Rows.Add("1", "1", "1", "1", "1")
    3. End Sub
    zu einem Fehler: "InvalidOperationException" Zum DataGridView-Steuerelement können nur Zeilen hinzugefügt werden, die Spalten enthalten. Die Spalten müssen zuerst hinzugefügt werden.
    Ich hatte schon überlegt eine Klasse anzulegen aber dann treten die selben Probleme auf ?(
    Grüße

    blubberbaum schrieb:

    Es ist eine von VB bereitgestellte Eingabebox.
    Ist eine nicht .NET kompatible von VB6 bereitgestellte ... deren Rückgabewert ein String ist, den Du einem Integer zuweist.
    Also fang an mit Option Strict On.
    -----------
    Leg Dir mal ein DGV im Designer an, füge diesem die erforderlichen Spalten hinzu und schreib den Code aus der FormX.Designer.vb, Prozedur InitializeComponents() ab.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany
    Woher war mir klar, dass das ne Fangfrage war.

    A

    RodFromGermany schrieb:

    Leg Dir mal ein DGV im Designer an, füge diesem die erforderlichen Spalten hinzu und schreib den Code aus der FormX.Designer.vb, Prozedur InitializeComponents() ab.



    Leider hab ich davon gerade soviel Ahnung wie eine halbe Scheibe Toast - das ist nicht dieses UserControl-Element?
    (Immer diese Nachteile von selbst Beigebrachten )
    Zieh dir im "Entwurf"-Modus (da, wo du deine Form siehst) einen DataGridView auf die Form und speichere es. Dann schau in der Datei Form1.Designer.vb (musst evtl. auf "alle Dateien anzeigen" klicken und "Form1.vb" aufspannen), was für Code automatisch hinzugefügt wurde. Den kannst du dann für deine Form übernehmen (und DGV wieder löschen).
    Mach Dir ein neues Projekt.
    Füge diesem ein DGV hinzu.
    Gib dem DGV 3 Spalten.
    Doppelklicke auf die Form.
    Klicke in den Zwischenraum zwischen Public Class Form1 und Private Sub Form_Load(...) ... und dann auf die rechte ComboBox:

    Klick auf InitializeComponent() und sieh Dir den Code an. :D
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Also. Die Methode mit dem Designer erzeugt mehr Fehler als ich hier aufzählen möchte.
    Der Versuch mit der globalen Variable ist geglückt - allerdings wird wenn man ein zweites DataGridView erstellt, wird das Erste gelöscht.
    Was ja auch logisch erscheint, da nur ein DGV erzeugt wurde.
    Eine Klasse DataGridView macht auch keinen Sinn (denke ich) weil ich ja zur Laufzeit keine Instanzen der Klasse Erzeugen kann.
    Bsp:

    VB.NET-Quellcode

    1. Dim Name as StringName = Label1.Text
    2. Dim Name as New KlasseDataGridView

    Wäre also noch der Versuch mit List (of DataGridView)

    Ich Dank erst mal alle Helfern.

    blubberbaum schrieb:

    Wäre also noch der Versuch mit List (of DataGridView)
    What?
    Du kannst nicht 2 Instanzen gleichen Namens erzeugen.

    VB.NET-Quellcode

    1. Dim dgv As New DataGridView
    Was geht daran nicht?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany

    Man nehme den obigen Quellcode und die Änderung von tomso. Dann wird beim ersten Klick auf Create ein neues Datagridview mit den entsprechenden Eigenschaften angelegt, ein neuer Tab wird dem TabControl1 hinzugefügt und das DGV auf dem Tab ausgegeben.
    Beim zweiten Klick wird dann ein zweiter Tab dem TabControl1 hinzugefügt und das DGV wird auf diesem angezeigt, allerdings verschwindet das DGV auf dem ersten Tab.
    Was imho daran liegt das wir nur eine DGV an eine Variable binden. Wie soll denn die Uterscheidung zwischen den einzelnen DGVs erfolgen wenn alle in nur einer Variablen liegen?.


    Einen Ansatz für eine Lösung war hier im Forum eine List(of T) in meinem Fall DatagridView

    VB.NET-Quellcode

    1. Public Class Form_Main
    2. Dim DGVListe As New List(Of DataGridView) 'Speichert alle DGV, in denen die Konten angelegt wurden
    3. Private Sub NeuToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles NeuToolStripMenuItem.Click
    4. 'Kontonummer erfragen und Funktion NeuesKonto() zum erstellen aufrufen
    5. Dim KTO As String
    6. KTO = InputBox("Kontonummer", "Neues Konto anlegen")
    7. If IsNumeric(KTo) Then
    8. NeuesKonto(KTo)
    9. Else : MsgBox("Nur Ziffern von 0-9, bitte!")
    10. End If
    11. End Sub
    12. Private Sub NeuesKonto(KTO As Integer)
    13. 'Erstellt ein neues Konto und legt dieses in einem neuen TAb ab.
    14. 'Button freigeben
    15. Button_Minus.Enabled = True
    16. Button_Plus.Enabled = True
    17. 'Neues DGV
    18. Dim DGV As New DataGridView 'erschafft ein neues DGV /neues Listenelement
    19. With DGV 'Eigenschaften definieren
    20. .EditMode = DataGridViewEditMode.EditProgrammatically 'manuelles hinzufügen deaktivieren
    21. .ReadOnly = True
    22. .AllowUserToAddRows = False
    23. .Columns.Add("position", "Position")
    24. .Columns.Add("datum", "Datum")
    25. .Columns.Add("betrag", "Betrag")
    26. .Columns.Add("belegnummer", "Belegnummer")
    27. .Columns.Add("rechungsnummer", "Rechnungsnummer")
    28. .Width = TabControl1.Width
    29. End With
    30. DGVListe.Add(DGV) 'Neues DGV der Liste hinzufügen
    31. 'Neuen Tab erstellen
    32. Dim TabIndex As Integer 'Anzahl der erstellten Tabs, bei keinem Tab ist der Index 0
    33. TabIndex = TabControl1.TabCount
    34. TabControl1.TabPages.Add(KTO) 'Tab hinzufügen mit KTO als Überschrift
    35. TabControl1.TabPages(TabIndex).Controls.Add(DGVListe(TabIndex)) 'TAb mit neuem DGV bestücken
    36. End Sub
    37. End Class


    Dies hat den gewünschten Effekt. Nun kann mit

    VB.NET-Quellcode

    1. DGVListe(INDEX).Rows.Add("1", "2", "3", "4", "5")

    eine zeile dem jeweiligen DGV hinzugefügt werden.

    Grüße

    blubberbaum schrieb:

    wenn alle in nur einer Variablen liegen?.
    Pro DGV eine Instanz. Klar.
    Vielleicht kanst Du mal was zu Deinem Plan schreiben, da wird der Code auch verständlicher.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Mein Plan...
    Zitat" Du kannst doch so gut mit Computern, da kannst du mir doch was programmieren"
    Am Ende soll ein einfache nKassensystem entstehen, damit mein Freund (Zitat oben) es in seinen Schulungen verwenden kann. Es gibt zwar schon viele fertige Programme für Schulungszwecke, aber mit denen ist er nicht so wirklich zufrieden.
    Im Anhang mal ein Screen wie es zur Zeit aussieht.
    Bilder
    • Kasse.PNG

      54,19 kB, 1.114×667, 234 mal angesehen
    Ah - kommt langsam Katze aussm Sack: Ein Kassensystem!

    Jo, wies mir aussieht, siehts sehr schlecht aus, weil du angefangen hast, die Oberfläche zu gestalten, ohne vorher überhaupt ein Datenmodell konzipiert zu haben - womöglich ist "Datenmodellierung" dir ühaupt kein Begriff.

    Da weißich jetzt garnet, wo anfangen, mittm Anfang.
    Also die Theorie der Datenmodellierung geht so: die relationale GrundIdee
    Viele praktische Umsetzungen davon findest du auf Daten laden, speichern, verarbeiten - unter annerem auch ein Kassensystem, allerdings wirklich nur ein Ladenkassen-System, also nur Artikel, Bons, BonPosten, wo man Einkäufe einhacken kann, und was "zu zahlen" ausrechnet.
    Wäre noch erweiterbar, dass Tags-/Wochen-.../Abrechnungen zugefügt würden, aber bei deim System tauchen ja Konten auf, also dein Kassensystem brauchst sicherlich ein ganz anners strukturiertes Datenmodell.
    Ja wie schon oben beschrieben bin ich halt kein VB-Profi. Datenbanken/Datenmodiellierung sagt mir was (Hatte da mal ein Semester Datenbanken), allerdings hatte ich keine wirklich Lust mich darin einzuarbeiten wie man in VB mit Datenbanken arbeitet. Klar ohne Zweifel wäre das weitaus professioneller, aber die Ergebnisse in einer TXT-Datei zu speichern war mir schon vertraut und damit das naheliegenste. Aber danke für dir Links ich werde mich bei Gelegenheit mal einlesen und vielleicht eine verbesserte Version schreiben.

    Grüße Blubber
    Datenmodellierung, wie ich sie immer (und auch in post#14) propagiere, hat eiglich garnix mit Datenbanken zu tun.
    zentrales Datenmodell ist das typisierte Dataset im Speicher, und da muß man sich einarbeiten, da geht kein Weg dran vorbei.
    Anschließend kannman wenn mans toll findet, eine Datenbank hinterlegen, aber auch wennman Datenbanken einsetzt, geht kein Weg anne Einarbeitung ins typDataset vorbei, weil im Speicher ist das typDataset, und die Datenbank ist auf Platte.
    Aber wie du selbst anstrebst: keine Datenbank, sondern Ergebnisse als Text-Datei abspeichern - dassis die Vorgehensweise, die ich propagiere. Meine Text-Dateien enthalten Xml-Code, weil das ist fürs typDataset am einfachsten zu lesen oder schreiben.

    ErfinderDesRades schrieb:



    Leider sieht man dann immer wieder, wie die Leuts die Daten aus dem DatagridView puhlen, und herumkonvertieren und komische Sachen machen.

    Ja allerdings, ich hab mich ganz schön verbogen um die Daten aus dem DGV zu speichern.

    Zu dem ersten Link: XML-Strukturen sind mir im Ansatz vertraut. Mein erster Gedanke (nicht immer mein Bester): Ist das nicht Way-too-much für meine paar Daten?

    XML-Quellcode

    1. <dgv>
    2. <Betrag>
    3. <Betrag1 />
    4. <Betrag2 />
    5. </Betrag>
    6. <Bezeichnung>
    7. <Bezeichnung1 />
    8. <Bezeichnung2 />
    9. </Bezeichnung>
    10. </dgv>

    Zu DataSet. Sieht auf jeden Fall eleganter aus :thumbup: . Allerdings habe ich damit noch nicht gearbeitet.
    Grüße Blubberbaum