InvokeRequired in eigener Klasse zugänglich machen / aus Form übernehmen

  • VB.NET

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

    InvokeRequired in eigener Klasse zugänglich machen / aus Form übernehmen

    Hallo zusammen,

    in einem Projekt habe ich eine Sub, die als Handler aufgerufen wird, wenn eine Kamera einen Frame liefert.

    In dieser Sub wird "InvokeRequired" abgefragt.

    Jetzt stehe ich vor folgendem Problem:
    Ist die Sub in einer Form im Projekt, funktioniert alles.
    Ist die Sub in einer Class im Projekt, dann ist "InvokeRequired" nicht bekannt.

    Ich habe schon herausgefunden, dass man das "InvokeRequied" irgendwie von Control (z.B. von Form) ableiten muss ("derive").
    Aber wie geht das?

    1000 Dank!
    Peter
    InvokeRequired ist eine Property in der Control Klasse. Wenn du dir nun mal die Vererbungsherachie von Form anschaust:
    learn.microsoft.com/de-de/dotn…m?view=windowsdesktop-8.0

    Siehst du auch Control, deshalb geht es in einer Form-Klasse(auch andere die Control innehaben), aber nicht in deiner. Soll nun nicht bedeuten das du deine Klasse von Control erben lassen sollst. Du braucht halt kontext in der Klasse. Dieser Kontext ist eine Instanz eines Form oder Control. Mach in die Klasse einen Konstruktor rein der ein Form als Parameter fordert, eine private Variable in der Klasse welche du im Konstruktor zuweist. Dann kannste das in deiner Klasse machen:

    VB.NET-Quellcode

    1. deineFormInstanz.InvokeRequired


    @Peter Vo
    Läuft das denn ausserhalb des UI Threads? Wenn nicht brauchste kein InvokeRequired abfragen und anschliessend invoken. Wenn du deine UI updatest ohne zu invoken, fliegt dir dann denn eine Exception um die Ohren? Wenn nicht, wirf das mit dem invoken raus.
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „DTF“ ()

    Danke für Deine schnelle Hilfe! Es funktioniert.

    Der Zugriff auf die Kamera erfolgt über eine eigene dll (VimbaNET.dll).
    Hier werden Frames angefragt und Events getriggert, wenn sie verfügbar sind.

    In meiner "Class AVT" (keine Form) rufe ich die Kamera-Routinen auf. Hier weise ich im Konstruktor der lokalen Variable VForm die "Form1", das Hauptfenster zu.

    Ich nutze den Beispielcode der dll zum Framegrabben mit InvokeRequired und Invoke. Warum das so wie von Dir beschrieben auch funktioniert, habe ich ehrlicherweise noch nicht 100%ig verstanden.
    Hieran wird es liegen:
    "Die Invoke -Methode durchsucht die übergeordnete Kette des Steuerelements, bis sie ein Steuerelement oder Formular mit einem Fensterhandle findet, wenn das dem aktuellen Steuerelement zugrunde liegende Fensterhandle noch nicht vorhanden ist."
    Quelle: learn.microsoft.com/de-de/dotn…e?view=windowsdesktop-8.0


    Obwohl "AVT" eigentlich "Form1" untergeordnet ist ...?
    Definiere "untergeordnet". Wenn du mit untergeordnet nicht Vererbung meinst wird was anderes sein. Kann sein das noch kein FensterHandle da ist, wenn du zu früh loslegst. Wäre auch gut wenn du uns Code zeigst was du nun gemacht hast.

    Hast du sowas gemacht?

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private cls As New TheClass(Me)' an dieser Stelle wäre noch kein Handle da wenn dann deine Klasse loslegt und es zum invokeversuch komm bevor das Form-Handle erstellt wurde, dann fliegst dir um die Ohren.
    3. ...
    4. End Class

    VB.NET-Quellcode

    1. Class TheClass
    2. Private frm As Form
    3. Public Sub New(frm As Form)
    4. Me.frm = frm
    5. End Sub
    6. End Class


    Das wäre dann der Fehler. Du hast ja gesagt du gibst das Form im Konstruktor rein. Dann zu einem späteren Zeitpunkt Form.Load, Form.Shown oder Control.HandleCreated(Form erbt ja von Control, somit gibst auch HandleCreate in Form) Event nutzen. Wenns nicht sowas ist, poste deinen Code.
    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D

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

    @Peter Vo Die Kamera arbeitet in einem separaten Thread und liefert Bilder, von denen sie der Meinung ist, dass Du sie anzeigen willst, dazu ist ein Invoke erforderlich.
    Wenn Du die Bilder nur abspeichern willst, ist kein Invoke erforderlich.
    Wenn Du aus Deiner eigenen Klasse ohne Invoke die Bilder an die GUI schickst, musst Du an dieser Stelle invoken, nicht aber in Deiner eigenen Klasse.
    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!
    Auf InvokeRequired brauchst du in deiem Falll nie zu testen, da dir ja bekannt ist, dass die Bilder immer nebenläufig entstehen.
    • Wenn Du die Bilder nur abspeichern willst, kann das im nebenläufigen Thread erfolgen - kein Invoke erforderlich - (und erstrecht kein Test auf InvokeRequired)
    • Wenn Du aus Deiner eigenen Klasse die Bilder an die GUI schickst, musst Du immer invoken - (ein Test auf InvokeRequired wird immer true ergeben - kannste dir also ebenfalls sparen)
    Falls frm.Invoke erforderlich ist: Es ist nicht nötig, ja sogar kontraproduktiv, extra zum Invoken ein Form zu erzeugen.
    Stattdessen nehme man das erstbeste Form, was in Application.OpenForms enthalten ist.
    Also sowas:

    VB.NET-Quellcode

    1. Application.OpenForms(0).Invoke(...)