DataGridView in TabControl als Thread bearbeiten

  • VB.NET

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von 13Hijack37.

    DataGridView in TabControl als Thread bearbeiten

    Hallo Leute,
    ich habe im Moment das Problem das ich nicht weiß wie ich in einem Thread auf ein Steuerelement
    in einem anderen Steuerelement zugreifen soll.
    In meinem Fall möchte ich auf ein DataGridView innerhalb eines TabControl zugreifen (.Rows.Add).

    Meinen bisherigen Code kann ich wohl nicht nutzen, der fügt auch nur per Invoke ein "Item" hinzu.
    Hatt vielleicht jemand mit einem TabControl und einem beliebigen Steuerelement das gleiche Problem?
    Oder weiß jemand wo man soetwas nachlesen kann? (Hab nichtmal in meinem Buch etwas gefunden)

    regards
    @13Hijack37
    Mach Dir eine geeignete DataTable, beatbeite im Thread die Daten, nicht aber das die Daten anzeigende Control, und wenn der Thread fertig ist, feuerst Du ein Event, worauf die DataTable im DGV angezeigt wird.
    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!

    13Hijack37 schrieb:

    an ein DataTable gebunden
    Da hast Du also ordentlich die Daten von der GUI getrennt. Daten sind im allgemeinen Thread-resistent, anders als GUI-Elemente. :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!

    13Hijack37 schrieb:

    Ok ich habe nun das DataGridView an ein DataTable gebunden.
    Funktioniert problemlos, wie kann ich nun aber aus einer Funktion aus einer anderen Klasse welche als Thread ausgeführt wird eine Zeile anfügen?
    Bei Databinding sollte man die Daten auch im MainThread einfügen, denn die Bindings greifen ja auch auf Controls zu, sodass unzulässige Zugriffe entstehen.
    Leider ist der Compiler nicht clever genug, auch solche Zugriffe anzumeckern. Stattdessen scheinen die Bindings einfach auszusetzen.
    Also auch bei Databinding: Control.Invoke() vs. .BeginInvoke() und weiterführende Links.

    Beachte, dass dort auch eine Lösung gegeben ist für den Fall, dass die Daten in einer Klasse anfallen, wo die gebundenen Controls nicht wirklich verfügbar sind.

    ErfinderDesRades schrieb:

    Bei Databinding sollte man die Daten auch im MainThread einfügen, denn die Bindings greifen ja auch auf Controls zu, sodass unzulässige Zugriffe entstehen.
    Leider ist der Compiler nicht clever genug, auch solche Zugriffe anzumeckern. Stattdessen scheinen die Bindings einfach auszusetzen.


    Danke!!! :love: Du hast mir gerade eine Antwort auf mein Problem geliefert, dass bei mir die Bindings nicht funktioniert haben (ich habe dann entnervt die Controls "ent"bunden und befülle sie manuell bzw. lese auch manuell die Daten aus). Ist allerdings ähnlich viel Code, als wenn ich die Daten im Main-Thread einfügen würde, dann müsste ich die Daten vom Nebenthread erst mühsam in eine Struktur/Klasse sammeln (da sind durchaus über 10 Elemente) und auf die dann in einer anderen Klasse manuell zum DataSet hinzufügen.
    Oder gibt es da eine andere Lösung?
    ich hab paar Extensions, mit denen ich die BindingSources entbinden kann, solange MassenOperationen auf den DataTables laufen. Anschließend wird wieder genauso gebunden, wies vorher war.
    Ein andermal habich rücksichtslos im Nebenthread herumgewurstelt, und einfach anschließen BindinSource.ResetBindings aufgerufen.
    Ah- was glaub auch solide ist, solange BindingSource.RaiseListChangedEvents=False zu setzen, denn in diesen Events spielt sich glaub die Databindelei ab.

    ErfinderDesRades schrieb:

    solange BindingSource.RaiseListChangedEvents=False zu setzen

    Aber die Daten werden in einer anderen Klasse befüllt, da habe ich gar keinen Zugriff auf die BindingSource (außer ich würde sie manuell im Konstruktor übergeben, dann kann ich auch gleich die Daten nach "oben" in die frmMain schicken, erscheint mir von der Logik und Architektur her sauberer)


    ErfinderDesRades schrieb:

    solange MassenOperationen auf den DataTables laufen. Anschließend wird wieder genauso gebunden, wies vorher war.

    Mein Problem war: das DataSet war richtig befüllt, die BindingSource hatte richtige Daten drin (habe in Überwachung nachgeschaut, was drin ist), ich habe im Hauptthread nochmal manuell Daten gesetzt - es wurde trotzdem nicht angezeigt. Deswegen mache ich es jetzt manuell und ohne Bindings, weil es mich einfach so genervt hat...

    In einer TestSolution hat leider alles funktioniert, kurzzeitig auch in meinem Projekt, und dann war wieder plötzlich alles beim Alten. ;(

    ErfinderDesRades schrieb:

    Wenn man da ein Form registriert

    Es ist aber keine Form. Ich habe einfach eine andere Klasse, die sich an der Stelle um die Daten für einen bestimmten Kanal bzw. Register vom Gerät kümmert. Bei Registern, denen ich im Konstruktor eine typ. DataRow übergebe, funktioniert das DataBinding wunderbar. Bei einem Register, bei dem ich das ganze DataSet übergebe, funktioniert es nicht.

    ABER: ich habe eben ausprobiert, auch da eine Row zu übergeben: es funktioniert trotzdem nicht :( . Wenn ich im Hauptthread beim Setzen der restlichen Eigenschaften (ich habe nur eine TextBox von vielen wieder gebunden, um zu prüfen, ob es funktioniert) die Row anschaue, steht der Wert drin. Die BindingSource.Position steht auf 0 (wo sie sein soll, es gibt nur den einen Datensatz), wenn ich BindingSource(0) im Überwachungsfenster anschaue, und da auf "Row" gehe, komme ich auf meine Row, wo dieser Wert auch gesetzt ist. Nur die TextBox, die an diese BS gebunden ist, zeigt nichts an ;(
    Warum funktioniert es bei anderen BS dann?
    In anderen BS hat es doch anscheinend nicht ganz funktioniert, auch wenn mehr, als in der einen. Aber jetzt habe ich das ausprobiert:

    ErfinderDesRades schrieb:

    Ein andermal habich rücksichtslos im Nebenthread herumgewurstelt, und einfach anschließen BindinSource.ResetBindings aufgerufen.


    Du bist wieder mein Held des Tages! :love:

    Ich sende aus den Datenklassen einfach ein Event an die MainForm, dass die Daten bereitstehen, und da mache ich ResetBindings, und schon funktioniert es! :thumbsup:
    Ich habe mich nun lieber dafür entschieden ein paar Funktionen in die Hauptklasse zu verschieben, das Problem der zweiten Frage besteht also nicht mehr.
    Trotzdem danke an alle die bei der eigentlichen Frage im Startpost geholfen haben, DANKE!

    best regards