Datenaustauisch zwischen Custom Control und Mainform

  • VB.NET
  • .NET 4.0

Es gibt 27 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Datenaustauisch zwischen Custom Control und Mainform

    Auf die Gefahr hin Prügel zu beziehen:
    Ich habe ein Custom Control erstellt welches in der übergeordneten Mainform eine Aktion auslösen soll.

    Hintergrund: Eine Comport-Schnittstelle (Custom Control) soll an die übergeordnete Mainform eine Datenbankabfrage senden und die Antwort dann empfangen und verarbeiten. (Einstellparameter von Comport aus Datenbank(sqlite) abfragen - und dann innerhalb der Custom Control mit den von der sqlite datenbank ausgelesenen Werten für den Comport und die Baudrate eine Verbindung öffnen)

    Warum als Custom Control? Ich möchte bis zu 24-Comports ansteuern. - Messgeräte.

    Dazu muss es
    1. Auf der Mainform ein ereigniss auslösen,
    1. dazu eine Variable mit dem DB-Abfragebefehl an die mainform übergeben
    3. die aus der abfrage erhaltenen daten wieder als inhalt iner variablen an das custom control übermitteln.


    DB-Abfragen gehen, Custom control kann ich erstellen und einbinden, was ich nicht hin bekomme ist die übergabe von Daten zwischen der Mainform und der Custom Control sowie das gegenseitige auslösen von Aktionen.
    Könnt ihr mir eventuell mit einem Beispiel weiterhelfen?
    Der Code sieht aktuell in etwa so aus.

    Custom Control:

    VB.NET-Quellcode

    1. Imports System
    2. Imports System.IO
    3. Imports System.Windows.Forms
    4. Imports System.ComponentModel
    5. Public Class UserControl1
    6. Dim form1 = New frmMain
    7. Public Sub kirchner_db_zugriff()
    8. form1.db_command = "Hallo welt"
    9. End Sub
    10. Private Sub Start_Click(sender As Object, e As EventArgs) Handles Start.Click
    11. kirchner_db_zugriff()
    12. End Sub
    13. end class


    die mainform sieht dann so aus:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Public db_command As String
    3. Public Function kirchner_db()
    4. TextBox1.Text = db_command
    5. End Function
    6. End Class


    ebenso soll die mainform wenn möglich auch eine funktion direkt in der custom control aufrufen können und dahin dann auch variablen übergeben.

    Hat mir eventuell jeman ein beispiel, was mache ich an der konfiguration falsch?

    Danke,

    JB
    jou
    Alles über Events

    Edit: Ups!
    Grad sehe ich dieses:

    VB.NET-Quellcode

    1. Public Class UserControl1
    2. Dim form1 = New frmMain

    Dassis ja der helle Wahn, innerhalb eines UserControls ein neues MainForm zu erzeugen.
    Mach dir mal die Bedeutung des New - Schlüsselwortes klar - Grundlagen: Fachbegriffe

    Und wie gesagt: korrektamente geht das mit Events.

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

    Danke erst mal für den Respond, ich bin weiter gekommen:

    Custom control:

    VB.NET-Quellcode

    1. Imports System
    2. Imports System.IO
    3. Imports System.Windows.Forms
    4. Imports System.ComponentModel
    5. Public Class UserControl1
    6. 'Dim form1 = New frmMain
    7. Public Event db_abfrage(db_command As String, e As EventArgs)
    8. Public Property db_command As Object
    9. Public Sub kirchner_db_zugriff()
    10. RaiseEvent db_abfrage(db_command, EventArgs.Empty)
    11. db_command = "Hallo welt"
    12. End Sub
    13. Private Sub Start_Click(sender As Object, e As EventArgs) Handles Start.Click
    14. kirchner_db_zugriff()
    15. End Sub
    16. End Class


    dann die Mainanwendung:

    VB.NET-Quellcode

    1. Imports System.Data.OleDb
    2. Imports System
    3. Imports System.Data
    4. Imports System.Data.SqlClient
    5. Imports System.Windows.Forms
    6. Imports comport3.UserControl1
    7. Public Class Form1
    8. Public Class StartEventArgs
    9. Inherits System.EventArgs
    10. End Class
    11. Sub db_aktion() Handles UserControl11.db_abfrage
    12. TextBox1.Text = "Hallo Welt"
    13. 'TextBox1.Text = UserControl1.db_command
    14. End Sub
    15. End Class


    Ich bekomme den event ausgelöst und er schreibt auch schön "Hallo Welt" - was noch fehlt, ist dass er den Wert in der Variable db_command in die Mainform überträgt.

    gedacht irgendwie : TextBox1.Text = UserControl1.db_command

    Danke,

    J.B.
    naja, du hast die entsprechende Zeile#16 ja auskommentiert - warum das?
    Wenn die eine Fehlermeldung verursacht, dann korrigiere deinen Code in geeigneter Weise - bei Auskommentieren passiert natürlich nix mehr.

    Am besten du gibst die Fehlermeldung wieder, dann kann man die eiglich total simple Lösung dir auch leicht begreiflich machen.
    danke, fehler gfunden und korrigiert.

    jetzt noch zum eingemachten.

    Ich möchte insgesamt bis zu 24 CustomControls in die Mainform ziehen und dann darin jeweils einen DB_abfrage iniziieren.

    Jetzt muss die DB natürlich noch wissen, von welcher der eingebundenen Custom controls abgefragt wird.

    geht da in etwa so?

    custom Control:

    VB.NET-Quellcode

    1. Imports System
    2. Imports System.IO
    3. Imports System.Windows.Forms
    4. Imports System.ComponentModel
    5. Public Class comport1
    6. 'Dim form1 = New frmMain
    7. Public Event db_abfrage(db_command As String, cc_adress As Object, e As EventArgs)
    8. Public Property db_command As String
    9. Public Property cc_adress As Object
    10. Public Sub kirchner_db_zugriff()
    11. db_command = MyClass.Name & "Hallo welt2"
    12. cc_adress = Me
    13. RaiseEvent db_abfrage(db_command, cc_adress, EventArgs.Empty)
    14. End Sub
    15. Private Sub Start_Click(sender As Object, e As EventArgs) Handles Start.Click
    16. kirchner_db_zugriff()
    17. End Sub
    18. End Class


    mainform:

    VB.NET-Quellcode

    1. Imports System.Data.OleDb
    2. Imports System
    3. Imports System.Data
    4. Imports System.Data.SqlClient
    5. Imports System.Windows.Forms
    6. Imports comport3
    7. Public Class Form1
    8. Public Class StartEventArgs
    9. Inherits System.EventArgs
    10. End Class
    11. Public Property db_command As Object
    12. Public Property cc_adress As Object
    13. Sub db_aktion() Handles Comport11.db_abfrage 'Comport12.db_abfrage
    14. 'TextBox1.Text = "Hallo Welt"
    15. TextBox1.Text = cc_adress.db_command
    16. End Sub
    17. End Class


    Der fehler ist: in TextBox1.Text = cc_adress.db_command
    und lautet:
    Ein Ausnahmefehler des Typs "System.NullReferenceException" ist in Microsoft.VisualBasic.dll aufgetreten.

    ich habe auch schon die varianten:

    TextBox1.Text = cc_adress.tostring + db_command und
    TextBox1.Text = cc_adress.tostring.db_command

    versucht
    das ist halt sehr ungeschickt, sogar unsinnig, dass du sowohl in Form1 eine Variable cc_adress als auch in UserControl1.

    Wozu ist die in Form1 gut? Lösch die, dann kriegst du einen Compiler-Fehler, der dich drauf bringt, wie's wirklich muss.

    Aber ich hab noch was viel dringenderes:
    Visual Studio - Empfohlene Einstellungen

    Weil dein' Code kann man eiglich nicht angucken ohne weinen zu müssen :(

    Bitte verschieb das nicht auf später, und noch später, denn je länger du die Deppen-Einstellungen drinne behälst, desto mehr Fehler baust du täglich ein.
    Also brings sofort in Ordnung, das geht - egal wie lange es dauert - am schnellsten.
    Weil dasses in Ordnung zu bringen ist, ist unumgänglich, und je später, desto schwieriger wird's.
    Hallo ErfinderdesRades,

    danke für die Hinweise, ich habe mir das Thema zu Herzen genommen und es auf Option Explicit On gesetzt, ich denke, dies vermeidet viele unnötige Folgefehler.

    Auch mit den events bin ich weiter gekommen.
    Ich habe jetzt aber noch eine Frage zur Erkennung, welche eingebundene CustomControl den event ausgelöst hat.

    Ich binde wie anfangs gesagt mehrmals die gleiche custom control ein um damit eine vielzahl an einzelnen COM-Ports zu steuern. (Ich will das als gekapselte CustomControl damit änderungen an der Comport Zugriff nur ein mal gemacht werden muss und es dann im Mainform einfach aktuallisiert)

    Die Comports legen die gelesenen Daten dann auf eine SQlite DB ab.

    es geht jetzt gut, dass die Comports ein event auf der Mainform auslösen, und dann über eine SUB in der Mainform die daten in eine SQlite-DB speichern.

    Wie kann ich aber erkennen, welche der einzelnen eingebundenen Custom Controls den event ausgelöst hat?

    VB.NET-Quellcode

    1. Sub db_aktion() Handles Cc_comport1.db_abfrage, Cc_comport2.db_abfrage, Cc_comport2.db_abfrage, .....


    gibt es da eine Rückmeldung in der ich feststellen kann ob es Cc_comport1; Cc_comport2 oder Cc_comportx war?

    janbronner schrieb:

    Wie kann ich aber erkennen, welche der einzelnen eingebundenen Custom Controls den event ausgelöst hat?
    Form1

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub UserControl11_MyTextEvent(sender As Object, e As MyEventArgs) Handles UserControl11.MyTextEvent, UserControl12.MyTextEvent, UserControl13.MyTextEvent
    3. If sender Is Me.UserControl11 Then
    4. Label1.Text = e.Text
    5. ElseIf sender Is Me.UserControl12 Then
    6. Label2.Text = e.Text
    7. ElseIf sender Is Me.UserControl13 Then
    8. Label3.Text = e.Text
    9. End If
    10. End Sub
    11. End Class
    UserControl

    VB.NET-Quellcode

    1. Public Class UserControl1
    2. Public Event MyTextEvent(sender As Object, e As MyEventArgs)
    3. Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
    4. RaiseEvent MyTextEvent(Me, New MyEventArgs(TextBox1.Text))
    5. End Sub
    6. End Class
    7. Public Class MyEventArgs
    8. Inherits EventArgs
    9. Public Property Text As String
    10. Public Sub New(txt As String)
    11. Me.Text = txt
    12. End Sub
    13. End Class
    UserControl mit TextBox,
    MainForm mit 3 dieser UserControls und 3 Labels.
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    Ich bin einen guten Schritt weiter, jetzt stehe ich habe vor dem nächsten Problem:

    ich habe das Custom Control erstellt und kann zwischen der Mainform und dem Custom Control Daten Tauschen.

    Ich würde gerne alle CC beim Anwendungsstrat aufrufen und ihnen einen definierten Initialwert übergeben.

    VB.NET-Quellcode

    1. Sub anwendung_startet() Handles Me.Load
    2. Cc_comport1.cc_comport_start()
    3. Cc_comport2.cc_comport_start()
    4. Cc_comport3.cc_comport_start()
    5. Cc_comport4.cc_comport_start()
    6. Cc_comport5.cc_comport_start()
    7. Cc_comport7.cc_comport_start()
    8. Cc_comport8.cc_comport_start()
    9. Cc_comport9.cc_comport_start()
    10. Cc_comport10.cc_comport_start()
    11. Cc_comport11.cc_comport_start()
    12. Cc_comport12.cc_comport_start()
    13. Cc_comport13.cc_comport_start()
    14. Cc_comport14.cc_comport_start()
    15. Cc_comport15.cc_comport_start()
    16. Cc_comport16.cc_comport_start()
    17. Cc_comport17.cc_comport_start()
    18. Cc_comport18.cc_comport_start()
    19. Cc_comport19.cc_comport_start()
    20. Cc_comport20.cc_comport_start()
    21. End Sub


    Dies ist so nätürlich sehr umständlich und sollte besser so irgendwie aussehen:

    VB.NET-Quellcode

    1. Sub anwendung_startet() Handles Me.Load
    2. for i = 1 to 20
    3. Cc_comport(i).cc_comport_start()
    4. next
    5. End Sub


    ich habe schon die callbyname funktion getestet:

    VB.NET-Quellcode

    1. Sub anwendung_startet() Handles Me.Load
    2. Dim bezeichnung_cc As String
    3. 'Dim übergabewert As String
    4. For i = 1 To 20
    5. bezeichnung_cc = "Cc_comport1" + i.ToString + ".cc_comport_start()"
    6. CallByName(Me, bezeichnung_cc, CallType.Let)
    7. Next
    8. End Sub


    ich bekomme aber leider keine fehlermeldung und ich habe die unterschiedlichen calltype. "let","get","set" und "method schon durchgetestet.

    hat mir jemand einen tipp?
    wenn all cccomports auf demselben Panel liegen kann man tatsächlich eine Schleife bauen.
    Liegen sie in verschiedenen Panels wirds komplizierter, dann muss man die Controls rekursiv durchgehen, und da kann man einfacher ein Array verwenden.

    Nur eines: Bitte nicht mit CallbyName.

    Übrigens dass dir dieser Schrott unter die Finger gerät, beweist mir, dass du meinen dringenden Rat nur halb umgesetzt hast, und fröhlich weiter unter dem Deppen-Namespace proggst.

    Ist das in Visual Studio - Empfohlene Einstellungen erzählte so unverständlich?

    janbronner schrieb:

    VB.NET-Quellcode

    1. Sub anwendung_startet() Handles Me.Load
    2. for i = 1 to 20
    3. Cc_comport(i).cc_comport_start()
    4. next
    5. End Sub
    Das geht so:

    VB.NET-Quellcode

    1. Sub anwendung_startet() Handles Me.Load
    2. Dim Cc_comport() = { Cc_comport1, Cc_comport2, Cc_comport3, Cc_comport4 }
    3. for i = 1 to 20
    4. Cc_comport(i).cc_comport_start()
    5. next
    6. End Sub

    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).
    VB-Fragen über PN / Konversation werden ignoriert!

    janbronner schrieb:

    festlegen
    Option Infer On.
    Ansonsten die Klasse Deines UserControls.
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    Bekomme ich noch Antwort auf die Frage, ob alle cccomponents im selben Panel liegen?
    Weil wie gesagt, dann ist eine noch einfachere Lösung angezeigt.

    Und handelt es sich um ein CustomControl oder um ein UserControl?
    Nach post#6 zu schließen nämlich um ein UserControl. Da würde ich vom Präfix cc_ dringend abraten, denn der ist irreführend. Und auch im Sprachgebrauch die Begriffe richtig benutzen.
    Ich habe nochmal eine Frage, die an dieses Thema anknüpft.
    Wie ich Daten oder Events vom Custom control zur mainform bekome ist mir klar und verstanden (denke ich).

    Ich habe jetzt noch eine Frage wie ich auf den Inhalt von variablen zugreifen kann. Mir ist klar, dass es im klassischen Weg so geht:

    VB.NET-Quellcode

    1. ' Daten in der mainform:
    2. dim variable as string
    3. variable = customcontrol.variable_cc



    In der Customcontrol dann


    VB.NET-Quellcode

    1. ' Daten im Customcontrol
    2. public variable_CC as string
    3. sub anzeige() Handle timer.tick
    4. txtbox1.text = variable_CC
    5. end sub


    Gibt es eine Möglichkeit in der Customcontrol direkt auf die in der übergeordneten Mainform abgelegten Daten zumindest lesend zuzugreifen?
    Es geht um mehrdimensionale Arrays in denen aus unterschiedlichen CC immer nur auf einen Teil der Daten in den Arrays (lesend) zugegriffen werden und Zyklisch ein Text in einer Übersicht angezeeigt werden soll.

    Danke,

    J.B.
    Das ist nicht vorgesehen, aber möglich.
    Du könntest:
    • das Mainform als Parameter ans CC übergeben und so auf die Public Fields des Mainforms zugreifen
    • die vom CC benötigten Daten direkt als Parameter übergeben
    • das CC fordert per Event das Mainform zum Datenreport auf
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.