Mit GDI+ eine Progressbar zeichnen

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von Leonalter.

    Mit GDI+ eine Progressbar zeichnen

    Hallo,

    ich lerne gerade GDI+

    Als ersten Test möchte ich eine Win 8 Progressbar zeichnen, das klappt eigentlich acuh ganz gut:



    Nun möchte ich aber die Value durch die Trackbar verändern.
    Aber wo schreibe ich das zum zeichnen hin?

    Das Form.Paint geht ja nicht.
    Ich habe da noch kleine Verständnisschwirigkeiten wegen dem Graphics, da ich dies ja nur in den PaintEventen habe, ich es doch aber in z.B. MouseHover auch bräuchte, oder?


    Würde mich über Hilfe sehr freuen
    Gruß
    Leon
    Das Control selbst sollte eine Property "Value" haben. Im Set-Part dieser Property (google hilft) kannst du darauf reagieren, wenn die Variable von außen verändert wird: Das control soll sich neuzeichnen, also einfahc invalidate aufrufen.

    Edit: Genauso ist das auch bei dem mouseHover. Du kannst feststellen, dass die Maus sich über dem Control befindet. Das musst du in einer boolean-Variable "zwischenspeichern" und das control neuzeichnen lassen (invalidate). Im Paint-Event/OnPaint-Sub zeichnest du anhand der gegebenen Eigenschaften. Wenn die BoolVariable true ist, dann befindet sich die maus drüber und iwas muss anders gezeichnet werden.
    Es geht hier ja nicht um ein Control, sondern um nur ein gezeichnetes.

    VB.NET-Quellcode

    1. Dim länge_verlauf As Integer = 0
    2. Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    3. With e.Graphics
    4. .DrawRectangle(New Pen(Color.FromArgb(203, 203, 203)), 10, 10, 360, 25)
    5. .FillRectangle(New SolidBrush(Color.FromArgb(230, 230, 230)), 11, 11, 359, 24)
    6. .FillRectangle(New Drawing2D.LinearGradientBrush(New Point(0, 0), New Point(0, 40), Color.FromArgb(8, 176, 41), Color.FromArgb(46, 191, 74)), 11, 11, länge_verlauf, 24)
    7. End With
    8. End Sub


    Kann ich es vielleicht zum neu zeichnen bringen wenn sich die Trackbar.value verändert?
    komplett falscher ansatz glaube ich. Warum machst du nicht ein "echtes" Control anstatt einfach nur eins auf die Form zu zeichnen?

    Aber ja, du kannst es:
    Im TrackBar.Scroll-Event kannst du auf eine Veränderung der Trackbar reagieren und den wert "länge_verlauf" entsprechend berechnen. Dann rufst du me.invalidate auf, damit sich die Form und damit dein Fake-Control neuzeichnet.

    Ich poste gleich noch eine kleine Alternative^^
    Zum Testen ist sowas natürlich mehr als OK, mache ich auch immer so^^

    In dem Fall möchtest du eine Progressbar nur anders darstellen. Funktionieren soll sie ja wie die herkömmliche. Und genau da kommt Vererbung ins Spiel. Du kannst ein eigenes Control erstellen und es von einem bestehenden erben lassen - das bedeutet, dass das eigene Control von grund auf über die Eigenschaften/Funktionen/etc wie das Ursprungscontrol verfügt. Jetzt hast du aber die Möglichkeit alles (naja, in einem gewissen Rahmen) umzubauen, z.b. so:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class MyProgressBar
    2. Inherits ProgressBar
    3. Public Sub New()
    4. 'Damit du das Control zeichnen kannst und nicht das Betriebsystem
    5. SetStyle(ControlStyles.UserPaint, True)
    6. End Sub
    7. Private _ProgressBarColor As Color = Color.Green
    8. Public Property ProgressBarColor() As Color
    9. Get
    10. Return _ProgressBarColor
    11. End Get
    12. Set(ByVal value As Color)
    13. _ProgressBarColor = value
    14. 'die Farbe hat sich geändert, das Control muss sich neuzeichnen:
    15. Me.Invalidate()
    16. End Set
    17. End Property
    18. 'Ist eigentlcih genau das gleiche wie das paint-event. Trotzdem sollte man Control-Intern das hier verwenden.
    19. Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
    20. Dim wertebereich As Integer = Maximum - Minimum '=> im normallfall von 0 bis 100, also einen Wertebereich von 100.
    21. Dim length As Integer = CInt((Value / wertebereich) * Me.Size.Width) 'Berechnet die länge des zu zeichnenden balkens
    22. With e.Graphics
    23. .Clear(BackColor)
    24. .FillRectangle(New SolidBrush(ProgressBarColor), 0, 0, length, Height)
    25. .DrawRectangle(New Pen(ProgressBarColor), 0, 0, Width - 1, Height - 1)
    26. End With
    27. End Sub
    28. End Class


    Auf die Art lernst du auch schnell in "mehreren Welten" zu denken. Ist ein wenig so, denn das Control funktioniert Intern fast genau wie die Form - du siehst nachher aber nichts mehr davon, es ist aber trotzdem da^^ Eine Besonderheit ist die Eigenschaft ProgressBarColor. Wenn diese sich ändert, willst du ja auch, dass es sofort sichtbar wird - es muss also sofort neu gezeichnet werden. Dafür eignen sich Properties wunderbar, du kannst kontrollieren, welche werte ein und ausgehen UND sogar eingreifen (z.b. darf die Breite des Controls nie negativ werden, etc).
    Wenn du ein komplett eigenes Control programmieren möchtest, dann musst du von Control erben (hier wird von progressbar geerbt).
    Um das Control zu nutzen kopiere den Code einfach unter den KlassenCode "Form1", debugge das Projekt einmal und schwupps ist das Teil in der Toolbox zu finden^^

    So, Das war jetzt nicht exakt das, was du gefragt hast aber egal^^ Auf jeden Fall ist es top, dass du erst mal etwas herumprobierst - gibt da beim Thema GDI auch ganz andere :wacko:

    lg
    Vielen Dank für die wirklich sehr hilfreiche Antwort, ich werde in Zukunft mir selbst meine COntrols erstrellen können :))

    Mit deinem GDI Tutorial muss man das ja verstehen, so gut wie das gemacht ist, hab mein test ein wenig ausgebaut, zwar kleine Sachen, aber schon schöne Spielerei, hab nämlich auch vor eigene Libs etc. jetzt zu machen :)



    Zwar nur eine Variablenspielerei, aber naja, zm üben :)



    Eine Frage hab ich aber noch, ich wollte probieren die Form zu zeichnen wie bei Windows 8, also:



    Ich habe nun die zwei Farben für den Übergang genommen, aber das sieht naja, schei*** aus.
    Wie bekommt man das mit der Transparenz hin?
    Würde mich ebenfalls interessieren.
    Endlich mal jemand, der sich mit den selben Gedankengängen befasst :D
    "Life isn't about winning the race. Life is about finishing the race and how many people we can help finish the race." ~Marc Mero

    Nun bin ich also auch soweit: Keine VB-Fragen per PM! Es gibt hier ein Forum, verdammt!
    Boa, das isn harter brocken xD Kenne dafür auch keine Lösung...

    Noch so eine Spielerei wäre TransparencyKey. Damit wenn du diesen Wert auf z.B. Rot festlegst und dann rote Linien auf die Form zeichnest wird sie an den Stellen durchsichtig. Da gibts aber keine Möglichkeit das iwie abzustufen...

    Einen Schatten hinzufügen geht auch noch so: visual-basic5.de/net/shadowform.htm
    Da hast du allerdings auch keine Einstellmöglcihkeiten und wie es unter WinXP aussieht kann ich auch nicht sagen^^
    Hey,

    ich verstehe nicht genau warum man bei Betriebsystemen wie XP ein Aero-Ähnlichen Effekt darstellen will, XP ist halt XP.

    Wenn wir weiterhin auf die Vergangenheit achten, steigern wir uns im Schnecken-Tempo, Win7 & Win8 darauf sollten wir uns konzentrieren.

    Just my 2 Sentences.

    Mfg
    sehe ich eigentlcih auch so. WinXP ist nicht dafür gemacht auszusehen wie win8. Du würdest ja auch nicht mit aller Gewalt versuchen mit ne Propellerflugzeug Mach 10 zu überschreiten xD

    @Nikx
    @TE
    Aber einen Weg sehe ich noch: vbforums.com/showthread.php?61…esktop-with-GDI&p=3997927
    damit ist es zumindest Möglich über den kompletten Bildschirm zu Zeichnen. Habe es grade selbst ausprobiert, wenn man mit einer Transparenten Farbe zeichnet, dann schimmert alles was darunter zu sehen ist durch. Damit könnte man nun einen Schatteneffekt der transparent ist um die Form zeichnen.
    Das Problem ist, dass man dem Desktop noch iwie sagen können müsste "zeichne dich neu", denn das müsste er tun wenn man die Form z.B. verschiebt.. Da gibts bestimmt noch ein paar weitere Tricks und Kniffe - da kenne ich mich aber wie schon gesagt weniger aus^^