MultiBar 2.3

    • Release

    Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von Artentus.

      Beschreibung:
      MultiBar ist ein vielseitiges und leicht anpassbares Benutzersteuerelement, das Funktionalitäten von TrackBar, ProgressBar und ScrollBar vereint und diese beliebig kombinierbar macht. Die MultiBar kommt standardmäßig im Windows-Stil daher, unterstützt aber auch komplettes Ownerdrawing für das Entwerfen eigener Stile.

      Screenshot:


      Klassendiagramm:


      Wie erstelle ich eigene Renderer?

      Spoiler anzeigen
      Die MultiBar ist dafür gedacht, eigene Stile dafür zu entwerfen.
      Wie ihr das anstellt werde ich nun anhand der beiden Beispiele auf dem Bild erklären.

      Zuerst müssen wir eigene Renderer erstellen. Dafür leiten wir eine Klasse von der MultiBarrenderer-Klasse ab:

      VB.NET-Quellcode

      1. Public Class BlueTrackBarRenderer : Inherits MultiBarRenderer
      2. Protected Overrides Sub OnDrawBar(e As MultiBarDrawEventArgs)
      3. End Sub
      4. End Class
      5. Public Class OrangeProgressBarRenderer : Inherits MultiBarRenderer
      6. Protected Overrides Sub OnDrawBar(e As MultiBarDrawEventArgs)
      7. End Sub
      8. End Class

      Dabei wird automatisch eine OnDrawBar-Methode generiert, wie ihr im Beispiel sehen könnt.
      Dort kommt nun das Ownerdrawing rein:

      VB.NET-Quellcode

      1. Friend Class BlueTrackBarRenderer : Inherits MultiBarRenderer
      2. Private Shared Sub DrawRoundedRectangle(ByVal g As Graphics, ByVal r As RectangleF, ByVal radius As Single, ByVal pen As Pen)
      3. Dim path As GraphicsPath = RectanglePath(r, radius)
      4. g.DrawPath(pen, path)
      5. path.Dispose()
      6. End Sub
      7. Private Shared Sub FillRoundedRectangle(ByVal g As Graphics, ByVal r As RectangleF, ByVal radius As Single, ByVal fillBrush As Brush)
      8. Dim path As GraphicsPath = RectanglePath(r, radius)
      9. g.FillPath(fillBrush, path)
      10. path.Dispose()
      11. End Sub
      12. Private Shared Function RectanglePath(ByVal r As RectangleF, ByVal radius As Single) As GraphicsPath
      13. Dim path As New GraphicsPath
      14. Dim d As Single = 2 * radius
      15. With path
      16. If radius < 1 Then
      17. .AddRectangle(r)
      18. Else
      19. .AddArc(r.X + r.Width - d, r.Y, d, d, 270, 90)
      20. .AddArc(r.X + r.Width - d, r.Y + r.Height - d, d, d, 0, 90)
      21. .AddArc(r.X, r.Y + r.Height - d, d, d, 90, 90)
      22. .AddArc(r.X, r.Y, d, d, 180, 90)
      23. End If
      24. .CloseFigure()
      25. End With
      26. Return (path)
      27. End Function
      28. Protected Overrides Sub OnDrawBar(e As MultiBarDrawEventArgs)
      29. Dim r = e.ElementRect
      30. Dim g = e.Graphics
      31. Select Case e.Element
      32. Case MultiBarElement.Slider
      33. Dim p As New GraphicsPath
      34. p.AddEllipse(r)
      35. Dim b As New PathGradientBrush(p)
      36. b.CenterPoint = New PointF(r.Width / 2.0F + r.X, r.Height / 2.0F + r.Y)
      37. b.CenterColor = Color.FromArgb(200, 200, 200)
      38. b.SurroundColors = {Color.FromArgb(140, 140, 140)}
      39. b.SetBlendTriangularShape(0.5F, 0.9F)
      40. b.FocusScales = New PointF(0, 0)
      41. Dim sliderRect As New RectangleF(r.X, r.Y + 0.5F, r.Width, r.Height - 1)
      42. g.FillEllipse(b, sliderRect)
      43. g.DrawEllipse(Pens.DimGray, sliderRect)
      44. b.Dispose()
      45. Case MultiBarElement.Bar
      46. Dim barRect As New RectangleF(r.X + 0.5F, 5.5F, r.Width - 1, 14)
      47. Dim b As New SolidBrush(Color.FromArgb(210, 210, 220))
      48. FillRoundedRectangle(g, barRect, 7, b)
      49. b.Dispose()
      50. Dim p As New Pen(Color.FromArgb(30, 30, 30), 1)
      51. DrawRoundedRectangle(g, barRect, 7, p)
      52. p.Dispose()
      53. Case MultiBarElement.Progress
      54. Dim progressRect As New RectangleF(r.X, 6, r.Width, 13)
      55. Dim b As New LinearGradientBrush(progressRect, Color.LightBlue, Color.Blue, LinearGradientMode.Vertical)
      56. FillRoundedRectangle(g, progressRect, 6, b)
      57. b.Dispose()
      58. End Select
      59. End Sub
      60. End Class
      61. Friend Class OrangeProgressBarRenderer : Inherits MultiBarRenderer
      62. Protected Overrides Sub OnDrawBar(e As MultiBarDrawEventArgs)
      63. Dim g = e.Graphics
      64. Select Case e.Element
      65. Case MultiBarElement.Bar
      66. g.FillRectangle(Brushes.LightSteelBlue, e.ElementRect)
      67. g.DrawRectangle(Pens.Gray, e.ElementRect.X + 0.5F, e.ElementRect.Y + 0.5F, e.ElementRect.Width - 1, e.ElementRect.Height - 1)
      68. Case MultiBarElement.Progress
      69. g.FillRectangle(Brushes.OrangeRed, e.ElementRect)
      70. g.FillRectangle(Brushes.Orange, New Rectangle(e.ElementRect.X, e.ElementRect.Y, e.ElementRect.Width, Convert.ToInt32(e.ElementRect.Height * 0.3)))
      71. End Select
      72. End Sub
      73. End Class

      Falls sich jemand fragt: Die ersten drei Funktionen in der BlueTrackBarRenderer-Klasse sind nur dafür da, die runden Ecken zu zeichnen.

      Und zu guter letzt müssen wir den MultiBars ihre Eigenschaften und Renderer zuweisen. Das machen wir am besten im Form_Load:

      VB.NET-Quellcode

      1. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
      2. Me.MultiBar1.ShowButtons = False
      3. Me.MultiBar1.SliderWidth = 24
      4. Me.MultiBar1.Style = MultiBar.MultiBarStyle.Progress
      5. Me.MultiBar1.Value = 50
      6. Me.MultiBar2.AllowScroll = False
      7. Me.MultiBar2.ShowButtons = False
      8. Me.MultiBar2.Style = MultiBar.MultiBarStyle.Progress
      9. Me.MultiBar2.ValueStyle = MultiBar.MultiBarValueStyle.Percent
      10. Dim renderer1 As New BlueTrackBarRenderer
      11. Dim renderer2 As New OrangeProgressBarRenderer
      12. MultiBar1.SetRenderer(renderer1)
      13. MultiBar2.SetRenderer(renderer2)
      14. End Sub


      Das ist aber natürlich nur ein kleiner Beispielcode den ich auf die Schnelle für die Demonstration geschrieben habe. Es gehen noch viel aufwändigere Dinge, eurer Fantasie ist quasi keine Grenze gesetzt. Aber ich hoffe dennoch ich konnte euch hiermit einen kleinen Überblick verschaffen, was alles möglich ist und wie ihr es anstellen könnt.


      Verwendete Programmiersprache und IDE:
      Visual Basic .NET (IDE: VS 2012 Ultimate)

      Systemanforderungen:
      .NET Framework 2.0

      Download:
      MultiBar.zip (20 kB)

      Changelog:

      Version 1.1
      - Fortschrittsbalken überdeckt nun nicht mehr den Rahmen des Hintergrunds
      - Rechteck des Fortschrittsbalkens bei CustomDraw angepasst

      Version 1.2
      - die Multibar aktualisiert sich nun nach Ändern von Min- und MaxValue
      - Fehler bei MinValue <> 0 behoben

      Version 1.3
      - Increment und Decrement Methoden hinzugefügt
      - ExactTick und StepValue Eigenschaften hinzugefügt
      - ButtonClicked Ereignis hinzugefürt
      - Renderqualität verbessert
      - Testanwendung verbessert

      Version 2.0
      - Beschreibungen und Standardwerte hinzugefügt
      - ExactTick-Eigenschaft durch LockStyle-Eigenschaft (mit mehr Möglichkeiten) ersetzt
      - Rendersystem komplett überarbeitet

      Version 2.1
      - kleine Änderung im Verhalten des Sliders
      - Direction-Eigenschaft hinzugefügt (entweder links-nach-rechts oder rechts-nach-links)

      Version 2.2
      - die MultiBar sollte nun nach Ändern von Min-/MaxValue neugezeichnet werden
      - Code aufgeräumt und optimiert

      Version 2.3
      - Renderbug der Trackbar mit Buttons behoben

      Lizenz/Weitergabe:
      Freeware, einkompilieren erlaubt

      Dieser Beitrag wurde bereits 9 mal editiert, zuletzt von „Artentus“ ()

      Das weniger... du könntest halt Eigenschaften wie Value,Min/MaxValue,... übernehmen doch da du Trackbar und Progressbar in einem hast und es sowas: msdn.microsoft.com/en-us/libra…primitives.rangebase.aspx in Winforms nicht gibt haste recht ja. Aber das Control ansich sieht gut aus :)


      Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
      Bei Custom würde ich noch den Code hier einfügen, sieht sonst finde ich zu trocken aus.

      VB.NET-Quellcode

      1. Dim glasTop As Color = Color.FromArgb(100, 255, 255, 255)
      2. Dim glasBottom As Color = Color.FromArgb(40, 255, 255, 255)
      3. Dim glass As New LinearGradientBrush(New Point(0, 0), New Point(0, BalkenH), glasTop, glasBottom)
      4. e.Graphics.FillRectangle(glass, 0, 0, BalkenB, CInt(BalkenH / 3))


      Und vielleicht noch bei "Default" den Rahmen über die Progressanzeige zeichnen, sonst sieht es etwas komisch aus.

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

      Die Designs im unteren Teil sind nur Beispiele für die Funktionalitäten der Bar, und nicht mit in der Lib enthalten. Wenn du auf Custom stellst kannst du alles an der Bar selbst zeichnen. Dafür wird dann für jedes Element das CustomDraw-Ereignis aufgerufen, in dem du völlige Gestaltungsfreiheit besitzt.

      Edit:
      Mit dem Ramen hast du recht, werde mich morgen mal darum kümmern.

      Version 1.3 online

      Da diesmal einige neue Features dazugekommen sind und nicht nur Bugfixes werde ich diese mal kurz beschreiben:

      - ExactTick: bestimmt, ob der Slider an den einzelnen Werten einrastet (so wie bei der TrackBar) oder nicht (stufenloses Ziehen)
      - StepValue: der Wert, um den Value bei Increment und Decrement oder bei einem Klick auf die Buttons verändert wird
      - Increment/Decrement: erhöht/verringert den Wert der Value-Eigenschaft um StepValue
      - ButtonClick: wird ausgelöst, wenn auf einen der Buttons geklickt wurde

      Außerdem habe ich den Screenshot, das Klassendiagramm und den Beispielcode aktualisiert.

      Version 2.0 fertig

      Da ich mit der bisherigen Lösung für das Ownerdrawing unzufrieden war habe ich mich mal dran gesetzt und das System komplett überarbeitet.
      Vorab aber noch ein paar kleine Änderungen:
      • Allen Eigenschaften wurde eine Default-Value zugeordnet und sie besitzen jetzt eine Beschreibung im Designer.
      • Die MultiBar besitzt in der Toolbox nun das Bild der ProgressBar und hat ebenfalls eine Beschreibung bekommen.
      • Die ExactTick-Eigenschaft wurde entfernt, dafür gibt es jetzt eine neue Eigenschaft LockStyle, die diese Funktion und eine weitere beinhaltet.

      Nun zur eigentlichen Neuerung:
      Das CustomDraw-Event und die EnableCustomDrawing-Eigenschaft wurden entfernt, da diese nun durch ein Renderer-System ersetzt werden.
      Die MultiBar besitzt jetzt zwei neue Methoden, SetRenderer und ResetRenderer. SetRenderer erwartet einen MultiBarRenderer, der verwendet werden soll. Man kann durch Erben vom MultiBarRenderer eben solch einen Renderer selbst schreiben. Wenn kein Renderer durch SetRenderer festgelegt wurde verwendet die MultiBar den nach außen nicht erreichbaren StandardRenderer. Dieser wird auch nach einem Aufruf an ResetRenderer verwendet. Das bringt den Vorteil, dass man den selben Renderer auf mehrere MultiBars anwenden kann ohne diese kennen zu müssen, und außerdem bekommt der Code eine bessere Struktur.

      Neues Update

      Eigentlich wollte ich diese Funktionen schon in die 2.0 einbauen, bin dann aber nicht mehr dazu gekommen. Deswegen gibts jetzt dieses weitere kleine Update. Da die Änderungen diesmal nicht sehr groß sind werde ich sie nicht extra beschreiben, sie stehen aber oben im ersten Post.
      Nein, das wird alles mit GDI+ gezeichnet. Bei den Standarddesigns wird der ScrollBar-/TrackBar-/ProgressBarRenderer verwendet, weswegen das dann so aussieht. Die Bar ist aber eigentlich dafür gemacht eigene Designs zu erstellen, weil das Windows-Design nicht sehr pralle aussieht, vor allem wenn man normalerweise nicht vorkommende Kombinationen verwendet (z.B. TrackBar mir Links/Rechts-Schaltflächen).
      @Artentus
      Ich hab es jetzt endlich mal runtergeladen :p
      Sieht wirklich verdammt gut aus und passt sehr gut zu Metro (sogar wenn man sich als Entwickler ungeschickt anstellt ;) )
      Nur eine kleine Kritik. Wenn man über die ToolBox die .dll hinzufügt sieht man kleine weiße Ränder.
      S.h. unten.
      (IDE: Visual Baisc Express 2010 & Windows 8 Pro 64Bit)
      Bilder
      • multibar.png

        624 Byte, 368×56, 296 mal angesehen
      • multibar.png

        685 Byte, 382×68, 288 mal angesehen

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

      @LaMiy
      So, also das auf dem zweiten Bild war ein Bug, den ich jetzt behoben hab, vielen Dank für den Hinweis.
      Die weißen Streifen kann ich jedoch leider nicht nachvollziehen, bei mir (Windows 7) wird es korrekt angezeigt. Das wird wohl irgendwie mit dem Metro-Stil zusammenhängen, doch da ich kein Windows 8 habe kann ich es leider nicht austesten.