INVOKE Problem mit ToolStripStatusLabel

  • VB.NET

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von BlackHook.

    INVOKE Problem mit ToolStripStatusLabel

    Hi Leute.
    Ich versuche von einen anderen Process auf ToolStripStatusLabel zu greifen.
    Soweit verstehe ich das Ganze, mit ToolStripStatusLabel kriege ich es aber nicht hin.
    Hier mein Code was funktioniert, wenn ich ein Label für Delegate nehme.
    Also über Umweg habe ich es zum laufen bekommen, ichmöchte aber nur mit ToolStripStatusLabel arbeiten.

    VB.NET-Quellcode

    1. Public Class Form1
    2. Dim TT As New Test
    3. Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    4. ToolStripStatusLabel2.ForeColor = Color.Red
    5. ToolStripStatusLabel2.Text = "Bitte warten bin beschäftigt......."
    6. With TT
    7. .ClassToolStripStatusLabel = Me.ToolStripStatusLabel2
    8. .ClassLabel = Me.Label1
    9. .BGW.RunWorkerAsync()
    10. End With
    11. End Sub
    12. End Class


    Und die Class

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Imports System.Windows.Forms
    3. Public Class Test
    4. #Region "Public"
    5. Private Label As Label
    6. Public Property ClassLabel() As Label
    7. Get
    8. Return Label
    9. End Get
    10. Set(ByVal value As Label)
    11. Label = value
    12. End Set
    13. End Property
    14. Private ToolStripStatusLabel1 As ToolStripStatusLabel
    15. Public Property ClassToolStripStatusLabel() As ToolStripStatusLabel
    16. Get
    17. Return ToolStripStatusLabel1
    18. End Get
    19. Set(ByVal value As ToolStripStatusLabel)
    20. ToolStripStatusLabel1 = value
    21. End Set
    22. End Property
    23. #End Region
    24. #Region "BGW"
    25. Public WithEvents BGW As New BackgroundWorker
    26. Dim Array(3) As String
    27. Private Sub BGW_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles BGW.DoWork
    28. 'Hier mach irgendwas
    29. End Sub
    30. Private Sub BGW_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BGW.RunWorkerCompleted
    31. Dim MyArray(0) As Object ' Übergabe an Deleage_Methode mit Array
    32. Label.BeginInvoke(New MyDelegate(AddressOf DelegateMethod), MyArray) ' Invoken
    33. End Sub
    34. #End Region
    35. #Region "Delegate"
    36. Delegate Sub MyDelegate(ByVal myControl As Label)
    37. Private Sub DelegateMethod(ByVal myControl As Label)
    38. ToolStripStatusLabel1.Text = "11111"
    39. Label.Text = "11111"
    40. End Sub
    41. #End Region
    42. End Class



    Hier habe ich es für ToolStripStatusLabel angepasst.

    VB.NET-Quellcode

    1. Private Sub BGW_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BGW.RunWorkerCompleted
    2. Dim MyArray(0) As Object ' Übergabe an Deleage_Methode mit Array
    3. ToolStripStatusLabel1.BeginInvoke(New MyDelegate(AddressOf DelegateMethod), MyArray) ' Invoken
    4. End Sub
    5. #End Region
    6. #Region "Delegate"
    7. Delegate Sub MyDelegate(ByVal myControl As ToolStripStatusLabel)
    8. Private Sub DelegateMethod(ByVal myControl As ToolStripStatusLabel)
    9. ToolStripStatusLabel1.Text = "11111"
    10. Label.Text = "11111"
    11. End Sub
    12. #End Region



    Leider bekomme ich nur eine Fehlermeldung
    "BeginInvoke" ist kein Member von "System.Windows.Forms.ToolStripStatusLabel".


    Bitte habt Verständnis, ich bin nur ein Anfänger.
    Bitte kommentiert die Antwort. Ich möchte das ganze verstehen können.
    Ehrlich gesagt verstehe ich nicht warum er das Control nicht akzeptieren will.
    Ich vermute dass mein Problem ein Anderer ist ,mein Control eigentlich ein StatusStrip ist.
    Mein Wissen reicht leider nicht aus um das Problem zu lösen. Probiert habe ich schon einiges.
    Bitte um Hilfe.

    BlackHook schrieb:

    Ehrlich gesagt verstehe ich nicht warum er das Control nicht akzeptieren will.

    hmm, die Lösung ist ganz einfach: das ToolstripItem stammt eben nicht von der Control-Klasse ab, hat deswegen auch keine Methoden Invoke/BeginInvoke . Schau Dir mal die Dokumentation von ToolstripStatusLabel auf MSDN an, dort ist die Basisklasse Component und nicht Control.

    Dennoch kannst Du Dein Problem leicht umgehen: Invoke und BeginInvoke sorgen ja nur dafür , daß Du auf den Thread switchst in dem das Control angelegt wurde. Insofern benutze zum Beispiel einfach das ToolStrip welche das ToolStripStatusLabel enthält oder sogar die Form zum Invoken.

    Noch 2 Fragen:
    - warum benutzt Du BeginInvoke statt Invoke ?
    - warum empfängst Du etwas unsauber in Deinem DelegateHandler 1 Label, obwohl Du ein ObjectArray übergibst ?


    P.S: wenn Du Threading, Delegates, Invokes und Parameterübergabe an Delegates nicht nur benutzt sondern auch verstanden hast, so giltst Du für mich nicht mehr als Anfänger ;)

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

    Danke danke danke.
    Ich bin immer noch ein Anfänger.
    Mit etwas umgehen zu können und etwas zu verstehen sind zwei verschieden Paar Schuhe.
    Ich habe das ganze nicht aus dem Kopf geschrieben (Das wäre KÖNNEN) . Ich habe mir die Infos aus dem Netz rausgesucht.
    Gelesen, probiert, irgendwann ein bisschen davon verstanden und umgesetzt.
    Das ist zu wenig um zu sagen ich bin kein Anfänger.
    Dein Tipp hat mir aber gereicht um es zu fixen.

    Hier ist es für Andere die es vielleicht gebrauchen könnten.

    VB.NET-Quellcode

    1. Public Class Form1
    2. Dim Test As New Test
    3. Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    4. ToolStripStatusLabel2.ForeColor = Color.Red
    5. ToolStripStatusLabel2.Text = "Bitte warten bin beschäftigt......."
    6. With Test
    7. .ClassToolStrip = Me.StatusStrip1
    8. .BGW.RunWorkerAsync()
    9. End With
    10. End Sub
    11. End Class
    12. Imports System.ComponentModel ' für den BGW
    13. Public Class Test
    14. #Region "Public"
    15. Private ToolStripStatusLabel As StatusStrip
    16. Public Property ClassToolStrip() As StatusStrip
    17. Get
    18. Return ToolStripStatusLabel
    19. End Get
    20. Set(ByVal value As StatusStrip)
    21. ToolStripStatusLabel = value
    22. End Set
    23. End Property
    24. #End Region
    25. #Region "BGW"
    26. Public WithEvents BGW As New BackgroundWorker
    27. Private Sub BGW_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles BGW.DoWork
    28. 'Mach sonst was
    29. End Sub
    30. Private Sub BGW_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BGW.RunWorkerCompleted
    31. Dim Text As String = Nothing
    32. ToolStripStatusLabel.Invoke(New MyDelegate(AddressOf DelegateMethod), Text)
    33. End Sub
    34. #End Region
    35. #Region "Delegate"
    36. Delegate Sub MyDelegate(ByVal myComponent As StatusStrip)
    37. Private Sub DelegateMethod(ByVal myComponent As StatusStrip)
    38. ToolStripStatusLabel.Items(1).Text = ("Ich bin die Änderung")
    39. End Sub
    40. #End Region
    41. End Class



    Noch 2 Fragen:
    - warum benutzt Du BeginInvoke statt Invoke ?
    - warum empfängst Du etwas unsauber in Deinem DelegateHandler 1 Label, obwohl Du ein ObjectArray übergibst ?


    Weil ich ehrlich gesagt nicht darauf geachtet habe, habe beides versucht gehabt, als BeginInvoke allerdings zuletzt, damit blieb es eben da.
    Ich lerne Autodidakt, Probieren geht über studieren. Habe nie schalltechnisch Programmieren gelernt. Werde es mit 46 auch nicht mehr machen.

    Zu deiner zweiten Frage.
    Ich glaube hier habe ich es verpeilt. Ich habe mehrere Parameter übergeben wollen, damit habe ich mir gedacht man müsste Array nehmen.
    Mittlerweile habe ich aber gesehen dass es Unfug ist. Ich habe 3 Parameter übergeben, ein Text für Label eingetragen, und trotzdem wurden alle drei Sachen übernommen.
    Hier fehlt es noch ein wenig am Verstand.


    Das "DelegateHandler" könntest du mir auf die einfache Weise erklären, falls du Lust dazu hättest.
    So verstehe ich es immer am besten.

    Für deine Hilfe bedanke ich mich herzlichst.
    Dann schiebe ich mal 2 Fragen nach:
    - warum benutzt Du eigentlich einen Backgroundworker ?
    - warum Parameterübergabe

    Der BGW ist ja eigentlich Threading für Dumme Faule: Invoken ist normalerweise unnötig, da 2 der 3 Eventhandler eh im normalen GUI Thread laufen: -> BGW Dokumentation
    - DoWork Event: läuft in einem eigenen Thread, bei Updates für den GUI-Thread wird normalerweise das Event ReportProgress aufgerufen
    - ProgressChanged Event: läuft auf dem GUI-Thread , also kein Invoke nötig
    - RunWorkerCompleted Event: wird aufgerufen wenn der BGW sich beendet/abgebrochen wird und läuft ebenfalls auf dem GUI-Thread

    Damit fällt auch die Parameterübergabe im üblichen Sinne flach, da die ReportProgress Methode nur einen Integer Wert als Parameter erlaubt. Werden sonstige Parameter benötigt so setzt man sie in (private) Variablen der Klasse.

    Entweder man benutzt den BGW mit seinen Vorzügen / Einschränkungen, aber dann konsequent. Oder man geht gleich auf einen Thread ( dediziert oder Threadpool).
    Wie ich schon geschrieben habe. Ich bin nur ein Anfänger, lernen ist angesagt, geht aber nur langsam voran.

    Oder man geht gleich auf einen Thread ( dediziert oder Threadpool).

    Da will ich hin. Ich arbeite mich langsam durch.
    Mein Projekt (Ich möchte es hier nicht erläutern was es ist, aber nichts böses) ist etwas aufwendiger als hier gepostet.
    Davor habe ich direkt BGW benutzt. Leider habe ich frieser beim Zugriff aufs Internet.
    Das ist nun nicht der Fall.
    Also hat es schon ein wenig gebracht.
    Ich bin aber recht motiviert und versuche mich soweit es mir möglich ist immer weiter zu entwickeln.
    Deshalb auch werde ich demnächst mehr zum Thema Threading lesen.
    Die jetzige Methode reicht aber aus um mein Projekt weiter zu bringen , daher mache ich erst da weiter.
    Step by step eben.

    Ich bin gerade auf der Arbeit. Wen ich nach hause komme schreibe ich dir eine PN mit kurzer Erklärung.
    Vielleicht kannst du mir ein Tip geben wie ich es besser realisieren könnte.
    Erst mal ist die Pause vorbei.