Klassenbibliothek / Eigenschaft / Progressbar

  • VB.NET

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

    Klassenbibliothek / Eigenschaft / Progressbar

    Hallo alle Zusammen,

    ich habe mir eine eigene Klassenbibliothek Programmiert die ein paar verschiedene Aufgaben erledigt (Excel-Tabellen auswerten).

    Jetzt habe ich das Problem wenn ich diese verschiedenen Funktionen in meiner Klassenbibliothek aufrufe von meinem Hauptprogramm sehe ich keinen Fortschritt bzw. kann diesen ja nicht abfragen.

    Jetzt habe ich mir überleget ob es sinnvoll wäre eine Eigenschaft als Object zu erstellen:


    VB.NET-Quellcode

    1. Private m_Progressbar As Object
    2. Public Property ProgressBar As Object
    3. Get
    4. Return m_Progressbar
    5. End Get
    6. Set(ByVal value As Object)
    7. m_Progressbar = value
    8. End Set
    9. End Property


    Und dieser dann eine Progressbar zuweisen – Jedoch habe ich das Problem das diese nicht immer Zuverlässig Arbeitet – In der Klassenbibliothek führe ich immer einen Refresh durch wenn ich den Wert ändere:

    VB.NET-Quellcode

    1. 'Progressbar
    2. m_Progressbar.Value = m_Progressbar + 1
    3. m_Progressbar.Refresh()


    Das seltsame ist jetzt wenn ich meine Klassenbibliothek aufrufe und verschiedene dinge Nacheinander ausführe hängt die Progressbar irgendwann bis der Sub fertig ist … meistens Funktioniert sie nur richtig beim ersten Sub danach nicht mehr daher habe ich auch ein DoEvents eingefügt ändert jedoch nichts ….

    VB.NET-Quellcode

    1. Sub Test
    2. Dim xlExcel As New xlExcel.Export
    3. xlExcel.FileName = “D:\test.xls”
    4. xlExcel.Progressbar = Progressbar1
    5. ‘Auslesen
    6. xlExcel.Auslesen
    7. Application.DoEvents()
    8. ‘Umwandeln
    9. xlExcel.Formatieren
    10. ‘Kopieren
    11. xlExcel.Kopieren
    12. End Sub


    Also in der Klassenbibliothek wird bei jedem Sub den ich hier jetzt Aufrufe die Progressbar immer Resetet also z.B. beim Kopieren Sub

    VB.NET-Quellcode

    1. 'Progressbar
    2. m_Progressbar.Minimum = 0
    3. m_Progressbar.Maximum = xlBook.Worksheets.Count
    4. m_Progressbar.Value = 0


    Ich verstehe nicht warum Windows oder viel mehr mein Programm die Progressbar nicht Aktualisiert – Oder ist die Lösung mit der Eigenschaft – Progressbar nicht gut? Ich habe auch schon viel gegoogelt aber jedoch nichts gefunden auch kein Codebeispiel das mir vielleicht weiterhelfen würde.
    Ein Control als Fortschritt in einer Bibliothek zu nehmen, ist eher schwachsinnig. Leg dir lieber eine Integer Variable an, in der du deinen Fortschritt schreibst, das hängen kommt dadurch, das der Main Thread durch dein Auswerten blockiert wird, deswegen wird auch die Progressbar nicht aktualisiert, lese dich zum Thema Threading, Events und Delegaten ein :)
    Wenn du aufwändige Aufgaben im GUI-Thread aufrufst, dann friert die Programmoberfläche (also auch die Progressbar) ein und reagiert erst wieder nach Beendigung. Um das zu umgehen solltest du deine Berechnungen in einem anderen Thread ausführen. Feuere dann immer einen Event, wenn sich der Fortschritt ändert und invoke es in deinem Hauptprogramm wieder in den GUI-Thread.
    Hallo,

    erstmal Dankeschön – Aber eine Integer Variable bringt mir ja nichts weil ich ja den Sub Aufrufe und dann nicht immer den Wert abfragen kann … oder habe ich da etwas falsch verstanden?

    Ich habe mich schon etwas eingelesen in Threading, Events und Delegaten und auch Beispielcodes gesucht und auch gefunden jedoch kann ich ja leider kein Event in meiner Klassenbibliothek erstellen und diesen dann in meinem Hauptprogramm nutzen soweit ich es verstanden habe …. Oder?

    Hmm ich bin irgendwie ratlos ... aber sehe ich es richtig das es absoluter mist ist ein Control einzubinden?

    Dankeschön
    Doch das kannst du, in den Fall würde dir die Integer Variable auch was bringen, da deine Klassenbilbiothek deinen Hauptprogramm unabhängig von der aktuellen Sub bescheid sagt, wenn sich was ändert ;)

    msdn.microsoft.com/de-de/library/vstudio/ms172877.aspx

    Scroll mal ein bisschen runter, da steht beschrieben, wie es geht.
    Hallo,

    erstmal dankeschön für den Link aber ich verstehe es leider nicht – Ich habe auch versucht ein kleines Beispiel zu finden im Internet leider ohne Erfolg – Hättest du vielleicht eins für mich das in etwa so etwas aufzeigt:

    Also wenn dies meine Klassenbibliothek wäre:

    VB.NET-Quellcode

    1. Public Class MyTest
    2. 'ProgressValue
    3. Private m_ProgressValue As Double
    4. ReadOnly Property ProgressValue As Double
    5. Get
    6. Return m_ProgressValue
    7. End Get
    8. End Property
    9. Sub Test()
    10. Dim Dummy As Integer
    11. Dim Progress As Double
    12. Progress = 100 / 3000000
    13. m_ProgressValue = 0
    14. For Dummy = 1 To 3000000
    15. m_ProgressValue = m_ProgressValue + Progress
    16. Next
    17. End Sub
    18. End Class

    Und ich hier mein Hauptprogramm:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    3. Dim X As New MyTest
    4. X.Test()
    5. End Sub
    6. End Class


    Hier hätte ich jetzt gerne ein Event immer wenn m_ProgressValue geändert wird soll es ausgelöst werden.

    Hoffe auf etwas Zeit von dir ...
    Oben ist Private m_Progressbar As Object deklariert, das ist nicht sinnvoll.
    Gib bitte Deinem Programm Option Strict On.
    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,

    also erstmal Dankeschön für dein Link – Ich habe es leider aber nicht verstanden oder ein einfaches Beispiel hinbekommen.

    Aber wenn ich es richtig verstanden habe ist es offenbar auch so nicht Möglich – Ich hätte gerne ein Event in meiner Klassenbibliothek welches ich in meinem Hauptprogramm aufrufen kann ….Also zum Beispiel

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Test As New MyClass1
    3. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    4. 'Event auslösen
    5. Test.Test()
    6. End Sub
    7. Private Sub MyHandle() Handles Test.MyVariableIntegerChanged
    8. 'Hier immer etwas ausführen wenn sich die in meiner Klasse die Variable m_Status ändert!
    9. End Sub
    10. End Class
    11. Public Class MyClass1
    12. Private m_Status As Integer
    13. Public ReadOnly Property Status As Integer
    14. Get
    15. Return m_status
    16. End Get
    17. End Property
    18. Sub Test()
    19. m_Status = 20
    20. End Sub
    21. End Class


    Also mir ist Selbstverständlich klar, dass dieser Code nicht Funktioniert. Aber genau so hätte ich es gerne realisiert … Doch möglich?

    Ich habe mir jetzt eine Notlösung gebastelt – Aber ich erörtere mal lieber nicht wie die aussieht sonst bekomme ich hier noch eine Ban! :)
    Ich hätte gerne ein Event in meiner Klassenbibliothek welches ich in meinem Hauptprogramm aufrufen kann
    hmm. Da haste vom Link wirklich nix verstanden, weil was du da gerne hättest ist Unfug, sry.
    Ist doch im Link haarklein erklärt: Eine Klasse löst ihr Event aus, und andere Klassen können das Event empfangen. Aber niemals kann die eine Klasse das Event einer anneren Klasse auslösen.

    wozu zum Kuckuk sollte bei dir Form1 das Event von MyClass auch auslösen - was willste damit bezwecken?

    RodFromGermany schrieb:

    Gib bitte Deinem Programm Option Strict On.
    Fang bitte am Anfang an und überspring nicht die ersten Stufen.
    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,

    @Artentus
    vielen lieben dank - Jetzt habe ich es geschafft! Mein Fehler war ich habe RaiseEvent nicht immer bzw. niemals in meiner Klassenbibliothek aufgerufen - Daher wurde das Event dann logischerweise niemals ausgelöst.

    @ErfinderDesRades
    Also den Link habe ich wirklich nicht verstanden - Also ich bin mit dem Beispiel nicht klargekommen: Eine Klasse löst ihr Event aus, und andere Klassen können das Event empfangen. Aber niemals kann die eine Klasse das Event einer anneren Klasse auslösen. Habe ich jedoch vorher schon verstanden - Ich habe es nicht geschafft in meiner Klassenbibliothek ein Event hinzuzufügen welches ich im Hauptprogramm dann aufrufen konnte also:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private WithEvents xlExcel As New xlExcel.Wareneingang
    3. Private Sub xlExcel_ProgressChanged() Handles xlExcel.ProgressChanged
    4. ProgressBar1.Value = xlExcel.Progress.Value
    5. ListBox1.Items.Add(xlExcel.Progress.Message)
    6. End Sub
    7. End Class


    So funktioniert es Super! Mein Fehler war einfach: RaiseEvent (In meiner Klassenbibliothek nicht ausgeführt).

    Jetzt habe ich mich etwas mehr damit beschäftigt und muss auch zugeben das dein Link sehr gut war / ist! - Ich war anfangs aber auch einfach nur Überfordert ein etwas leichteres Beispiel habe ich dann aber zum Glück doch noch gefunden.

    Ich habe anfangs eine Progressbar in meiner Bibliothek übernommen - Was jedoch Schwachsinn war / ist. Nun wird immer mein Event ausgelöst wenn sich mein Fortschritt ändert und mein Hauptprogramm kann reagieren - In meinem fall den Fortschritt in eine Progressbar darstellen.

    Oder ist diese Lösung nun auch nicht gerade Optimal?

    @RodFromGermany
    Meine Anwendung muss viel mit Excel Arbeiten: Auslesen, Schreiben, Formatieren ... Ich mag die Unabhängigkeit der späten Bindung - Die spätere Bindung ermitteln welche Excel.Application vorhanden ist:

    VB.NET-Quellcode

    1. Private xlApp As Object = CreateObject("Excel.Application")


    Und da ich Option Strict On nicht mit später Bindung verwenden kann muss es halt einfach wegbleiben. Oder hast du da eine bessere Idee?

    Timi01 schrieb:

    Eine Klasse löst ihr Event aus, und andere Klassen können das Event empfangen. Aber niemals kann die eine Klasse das Event einer anneren Klasse auslösen. Habe ich jedoch vorher schon verstanden - Ich habe es nicht geschafft in meiner Klassenbibliothek ein Event hinzuzufügen welches ich im Hauptprogramm dann aufrufen konnte also:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private WithEvents xlExcel As New xlExcel.Wareneingang
    3. Private Sub xlExcel_ProgressChanged() Handles xlExcel.ProgressChanged
    4. ProgressBar1.Value = xlExcel.Progress.Value
    5. ListBox1.Items.Add(xlExcel.Progress.Message)
    6. End Sub
    7. End Class
    Du drückst dich völlig falsch aus. Was du sagst "Event im Hauptprogramm aufrufen" ist weiterhin Unfug.
    Aber der Code, den du zeigst, ist völlig korrekt. Nur ruft der kein Event auf, sondern er empfängt eines.

    Es ist ungemein wichtig, die Begriffe richtig zu handhaben. Ansonsten gibt es keine funktionierende Kommunikation, und im Grunde kann man nichtmal zielführend denken, wenn man in einem Begriffs-Wirrwar verstrickt ist.

    Timi01 schrieb:

    Ich mag die Unabhängigkeit der späten Bindung
    OK.
    Dann kapsele die Excel-Zugriffe in einer separaten Klasse mit Option Strict Off und gib Deinem Programm Option Strict On.
    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!
    @ErfinderDesRades
    Da hast Selbstverständlich vollkommen recht - Dies war offenbar mein Denkfehler und auch Ausdrucksfehler jedoch wusste ich es auch nicht besser.

    @RodFromGermany
    Habe ich gemacht - So bin ich auch zu dem Problem hier gekommen! :)