ChartControl erweitern

  • VB.NET

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

    ChartControl erweitern

    Hallo zusammen,

    ich möchte gerne das ChartControl mit weiteren Propertys und Funtkionalitätet erweitern. Dazu habe ich schon mal folgenden Code:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class XChart
    2. Inherits Charting.Chart
    3. Private Property SeriesColor As List(Of Color)
    4. ''' <summary>
    5. ''' "Begrenzt die Anzahl und Erzeugt die Kurven-Serien für das Diagramm"
    6. ''' </summary>
    7. ''' <remarks></remarks>
    8. Private _MaxAnzahSeries As Integer
    9. <Description("Begrenzt die Anzahl und Erzeugt die Kurven-Serien für das Diagramm")> _
    10. Public Property MaxAnzahlSeries() As Integer
    11. Get
    12. Return _MaxAnzahSeries
    13. End Get
    14. Set(ByVal value As Integer)
    15. If MaxAnzahlSeries <> value Then
    16. _MaxAnzahSeries = value
    17. Call CreateSeries()
    18. End If
    19. End Set
    20. End Property
    21. Public Sub New()
    22. MyBase.New()
    23. SeriesColor = New List(Of Color)
    24. SeriesColor.Add(Color.Green)
    25. SeriesColor.Add(Color.Orange)
    26. SeriesColor.Add(Color.Brown)
    27. SeriesColor.Add(Color.Chocolate)
    28. SeriesColor.Add(Color.CornflowerBlue)
    29. SeriesColor.Add(Color.Crimson)
    30. SeriesColor.Add(Color.DarkMagenta)
    31. SeriesColor.Add(Color.DeepPink)
    32. SeriesColor.Add(Color.Firebrick)
    33. SeriesColor.Add(Color.ForestGreen)
    34. SeriesColor.Add(Color.Gold)
    35. SeriesColor.Add(Color.Maroon)
    36. SeriesColor.Add(Color.Magenta)
    37. SeriesColor.Add(Color.Moccasin)
    38. SeriesColor.Add(Color.OliveDrab)
    39. SeriesColor.Add(Color.OrangeRed)
    40. SeriesColor.Add(Color.PaleVioletRed)
    41. SeriesColor.Add(Color.Red)
    42. SeriesColor.Add(Color.RoyalBlue)
    43. SeriesColor.Add(Color.SaddleBrown)
    44. SeriesColor.Add(Color.SeaShell)
    45. SeriesColor.Add(Color.SteelBlue)
    46. SeriesColor.Add(Color.Tan)
    47. SeriesColor.Add(Color.Teal)
    48. SeriesColor.Add(Color.Thistle)
    49. SeriesColor.Add(Color.Tomato)
    50. SeriesColor.Add(Color.Turquoise)
    51. SeriesColor.Add(Color.Violet)
    52. SeriesColor.Add(Color.Wheat)
    53. SeriesColor.Add(Color.Yellow)
    54. SeriesColor.Add(Color.YellowGreen)
    55. Dock = DockStyle.Fill
    56. ChartAreas.Add("ChartArea1")
    57. ChartAreas(0).AxisX.LabelStyle.Format = "{dd/MM/yy | HH:mm:ss}"
    58. Legends.Add("Legend1")
    59. End Sub
    60. Private Sub CreateSeries()
    61. '________________________________________________________________________________
    62. 'Serien erzeugen und laden
    63. For i As Integer = 1 To _MaxAnzahSeries
    64. With Me
    65. Dim DiagrammSerie As DataVisualization.Charting.Series
    66. DiagrammSerie = .Series.FindByName(CStr(i))
    67. If IsNothing(DiagrammSerie) = True Then
    68. .Series.Add(i)
    69. .Series(CStr(i)).ChartType = DataVisualization.Charting.SeriesChartType.FastLine
    70. .Series(CStr(i)).ChartArea = "ChartArea1"
    71. .Series(CStr(i)).Legend = "Legend1"
    72. .Series(CStr(i)).XValueType = DataVisualization.Charting.ChartValueType.DateTime
    73. .Series(CStr(i)).Color = SeriesColor(i)
    74. End If
    75. End With
    76. Next
    77. End Sub



    Über die Property MaxAnzahlSeries werden entsprechend FastLine-Series erzeugt.

    Ich kann das Control auch auf meine Form ziehen und es werden im Designer entsprechend der Anzahl die Series gezeichnet.
    Will ich dann aber das Programm starten bekomme ich folgende Fehlermeldung:

    Spoiler anzeigen

    Fehler beim Erstellen des Formulars. Weitere Informationen finden Sie in Exception.InnerException. Fehler: Ein Diagrammelement mit dem Namen '1' ist bereits in 'SeriesCollection' vorhanden..



    Ist ja klar, da ich ja über die Property im Designer schon 1 Serie zeichnen lies.
    Wieso erkennt mein Control nicht, dass schon eine Serie vorhanden ist??

    Hoffe mir kann jemand helfen!
    Danke!
    Gruß von der KSE

    ks-entwicklung.de

    KSE schrieb:

    1 Serie zeichnen
    Per Default kommt das Chart mit 4 Series, die solltest Du vorher löschen.
    Absonsten müsstest Du eine AddNewSeries-Funktion schreiben / überschreiben oder aufrufen, die dann genau das tut und die korrekt vom Framework aufgerufen 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!
    Der Designer jammert immer noch rum, auch wenn ich die Series lösche. Desweiteren versuche ich darauf zu reagieren, ob ich im DesignMode oder im Runtime bin.
    Das interessante ist, dass mein Programm trotzdem funktioniert. Ich muss halt immer im Designer den "Fehler Ignorieren und fortfahren"...


    Spoiler anzeigen


    VB.NET-Quellcode

    1. Public Class XChart
    2. Inherits Charting.Chart
    3. Private Property SeriesColor As List(Of Color)
    4. ''' <summary>
    5. ''' "Begrenzt die Anzahl und Erzeugt die Kurven-Serien für das Diagramm"
    6. ''' </summary>
    7. ''' <remarks></remarks>
    8. Private _MaxAnzahlSeries As Integer = 1
    9. <Description("Begrenzt die Anzahl und Erzeugt die Kurven-Serien für das Diagramm")> _
    10. Public Property MaxAnzahlSeries() As Integer
    11. Get
    12. Return _MaxAnzahlSeries
    13. End Get
    14. Set(ByVal value As Integer)
    15. If _MaxAnzahlSeries <> value Then
    16. _MaxAnzahlSeries = value
    17. Call CreateSeries()
    18. End If
    19. End Set
    20. End Property
    21. Public Sub New()
    22. MyBase.New()
    23. Dim addDataThreadStart As New ThreadStart(AddressOf AddDataThreadLoop)
    24. addDataRunner = New Thread(addDataThreadStart)
    25. addDataDel = New AddDataDelegate(AddressOf AddData)
    26. SeriesColor = New List(Of Color)
    27. SeriesColor.Add(Color.Green)
    28. SeriesColor.Add(Color.Orange)
    29. SeriesColor.Add(Color.Brown)
    30. SeriesColor.Add(Color.Chocolate)
    31. SeriesColor.Add(Color.CornflowerBlue)
    32. SeriesColor.Add(Color.Crimson)
    33. SeriesColor.Add(Color.DarkMagenta)
    34. SeriesColor.Add(Color.DeepPink)
    35. SeriesColor.Add(Color.Firebrick)
    36. SeriesColor.Add(Color.ForestGreen)
    37. SeriesColor.Add(Color.Gold)
    38. SeriesColor.Add(Color.Maroon)
    39. SeriesColor.Add(Color.Magenta)
    40. SeriesColor.Add(Color.Moccasin)
    41. SeriesColor.Add(Color.OliveDrab)
    42. SeriesColor.Add(Color.OrangeRed)
    43. SeriesColor.Add(Color.PaleVioletRed)
    44. SeriesColor.Add(Color.Red)
    45. SeriesColor.Add(Color.RoyalBlue)
    46. SeriesColor.Add(Color.SaddleBrown)
    47. SeriesColor.Add(Color.SeaShell)
    48. SeriesColor.Add(Color.SteelBlue)
    49. SeriesColor.Add(Color.Tan)
    50. SeriesColor.Add(Color.Teal)
    51. SeriesColor.Add(Color.Thistle)
    52. SeriesColor.Add(Color.Tomato)
    53. SeriesColor.Add(Color.Turquoise)
    54. SeriesColor.Add(Color.Violet)
    55. SeriesColor.Add(Color.Wheat)
    56. SeriesColor.Add(Color.Yellow)
    57. SeriesColor.Add(Color.YellowGreen)
    58. XchartYValues = New List(Of Decimal)
    59. Series.Clear()
    60. ChartAreas.Clear()
    61. Legends.Clear()
    62. Dock = DockStyle.Fill
    63. If DesignMode = True Then
    64. If ChartAreas.Count = 0 Then
    65. ChartAreas.Add("ChartArea1")
    66. End If
    67. If Legends.Count = 0 Then
    68. Legends.Add("Legend1")
    69. End If
    70. With Me
    71. .ChartAreas(0).CursorY.IsUserEnabled = True
    72. .ChartAreas(0).CursorY.IsUserSelectionEnabled = True
    73. .ChartAreas(0).AxisY.ScaleView.Zoomable = True
    74. .ChartAreas(0).AxisY.ScrollBar.IsPositionedInside = False
    75. ' Set automatic zooming
    76. .ChartAreas(0).AxisY.ScaleView.Zoomable = True
    77. ' Set automatic scrolling
    78. .ChartAreas(0).CursorY.AutoScroll = True
    79. .ChartAreas(0).CursorX.IsUserEnabled = True
    80. .ChartAreas(0).AxisX.ScrollBar.Enabled = True
    81. .ChartAreas(0).CursorX.IsUserSelectionEnabled = True
    82. .ChartAreas(0).CursorX.IntervalType = System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Seconds
    83. .ChartAreas(0).CursorX.Interval = 0D
    84. .ChartAreas(0).AxisX.ScaleView.SmallScrollSizeType = DateTimeIntervalType.Seconds
    85. .ChartAreas(0).AxisX.ScaleView.SmallScrollSize = 0.01 '0D
    86. .ChartAreas(0).AxisX.ScaleView.SmallScrollMinSize = 0.01
    87. .ChartAreas(0).AxisX.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Seconds
    88. .ChartAreas(0).AxisX.ScaleView.Zoomable = True
    89. .ChartAreas(0).AxisX.LabelStyle.Format = "{dd/MM/yy | HH:mm:ss}"
    90. For Each ser As Series In .Series
    91. ser.XValueType = DataVisualization.Charting.ChartValueType.DateTime
    92. Next
    93. End With
    94. End If
    95. End Sub
    96. Private Sub CreateSeries()
    97. If DesignMode = True Then
    98. '________________________________________________________________________________
    99. 'Serien erzeugen und laden
    100. Series.Clear()
    101. For i As Integer = 1 To _MaxAnzahlSeries
    102. With Me
    103. .Series.Add(i)
    104. .Series(CStr(i)).ChartType = DataVisualization.Charting.SeriesChartType.FastLine
    105. .Series(CStr(i)).ChartArea = "ChartArea1"
    106. .Series(CStr(i)).Legend = "Legend1"
    107. .Series(CStr(i)).XValueType = DataVisualization.Charting.ChartValueType.DateTime
    108. .Series(CStr(i)).Color = SeriesColor(i)
    109. 'End If
    110. End With
    111. Next
    112. End If
    113. End Sub
    114. End Class



    Gruß von der KSE

    ks-entwicklung.de
    @KSE:: Im Konstruktor hantierst Du mit einem Thread rum?
    Wahrscheinlich musst Du einige Properties geeignet setzen und / oder überschreiben.
    Ich denke mal, der hat iwo eine Item-List, die müsstest Du anzapfen.
    Ich würde erst mal mit wenigen Serian anfangen, damit das Testen nicht so lange dauert.
    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!
    Ja, die Messwerte werden in einem eigenen Thread erfasst, damit es flüssig läuft. Ich habe hier den abgespeckten Code reingestellt, da es sonst zu kompliziert wird.
    Wie gesagt mein Control funktioniert wunderbar bis auf den Designer ..
    Kann man im Designmode irgendwie debuggen, um den Fehler zu finden?
    Wenn ich mein Control auf die Form ziehe zeichnet er ja die Serien rein. Wenn ich dann die Form schließe wird gefragt, ob
    ich die Änderungen speichern will (logisch neues Control auf der Form). Nach erneutem Aufrufen der Form bekomme ich dann den Fehler, dass die Serien schon vorhanden sind.
    Schaut man in die Form1.Designer.vb steht auch alles wunderbar drin wie es sein soll ...

    Spoiler anzeigen

    VB.NET-Quellcode

    1. '
    2. 'XChart1
    3. '
    4. Me.XChart1.ChangedAnnotationText = Nothing
    5. ChartArea1.AxisX.LabelStyle.Format = "{dd/MM/yy | HH:mm:ss}"
    6. ChartArea1.AxisX.Maximum = 41695.358373912037R
    7. ChartArea1.AxisX.ScaleView.SmallScrollMinSize = 0.01R
    8. ChartArea1.AxisX.ScaleView.SmallScrollMinSizeType = System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Minutes
    9. ChartArea1.AxisX.ScaleView.SmallScrollSize = 0.01R
    10. ChartArea1.AxisX.ScaleView.SmallScrollSizeType = System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Minutes
    11. ChartArea1.AxisY.ScrollBar.IsPositionedInside = False
    12. ChartArea1.CursorX.Interval = 0.0R
    13. ChartArea1.CursorX.IntervalType = System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Minutes
    14. ChartArea1.CursorX.IsUserEnabled = True
    15. ChartArea1.CursorX.IsUserSelectionEnabled = True
    16. ChartArea1.CursorY.IsUserEnabled = True
    17. ChartArea1.CursorY.IsUserSelectionEnabled = True
    18. ChartArea1.Name = "ChartArea1"
    19. Me.XChart1.ChartAreas.Add(ChartArea1)
    20. Me.XChart1.ChartZoomMode = False
    21. Me.XChart1.Dock = System.Windows.Forms.DockStyle.Fill
    22. Me.XChart1.KoordinatenAnzeigen = False
    23. Legend1.Name = "Legend1"
    24. Me.XChart1.Legends.Add(Legend1)
    25. Me.XChart1.Location = New System.Drawing.Point(0, 0)
    26. Me.XChart1.MaxAnzahlSeries = 2
    27. Me.XChart1.Name = "XChart1"
    28. Me.XChart1.ScrollToNewestValues = False
    29. Series1.ChartArea = "ChartArea1"
    30. Series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastLine
    31. Series1.Color = System.Drawing.Color.Orange
    32. Series1.Legend = "Legend1"
    33. Series1.Name = "1"
    34. Series1.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.DateTime
    35. Series2.ChartArea = "ChartArea1"
    36. Series2.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastLine
    37. Series2.Color = System.Drawing.Color.Brown
    38. Series2.Legend = "Legend1"
    39. Series2.Name = "2"
    40. Series2.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.DateTime
    41. Me.XChart1.Series.Add(Series1)
    42. Me.XChart1.Series.Add(Series2)
    43. Me.XChart1.Size = New System.Drawing.Size(781, 468)
    44. Me.XChart1.StartMesswerteErfassen = False
    45. Me.XChart1.TabIndex = 0
    46. Me.XChart1.Text = "XChart1"
    47. Me.XChart1.XchartYValues = CType(resources.GetObject("XChart1.XchartYValues"), System.Collections.Generic.List(Of Decimal))



    Gruß von der KSE

    ks-entwicklung.de

    KSE schrieb:

    Kann man im Designmode irgendwie debuggen, um den Fehler zu finden?
    ja, das geht sogar irgendwie.

    Aber das war eine besondere und komische Einstellung, da liefen dann iwie 2 VisualStudios auf derselben Solution - ach ich hab vergessen wie das ging.
    Aber es ist definitiv möglich, und sollte sich re-recherchieren lassen.
    Okay, ich habe es jetzt hin bekommen im Designmode zu debuggen. Danke ErfinderDesRades.
    Es verhält sich folgendermaßen:

    Jedes mal, wenn die Form geöffnet wird (Design Ansicht) wird die Public Sub New() ausgeführt. Aber in dieser Sub wird nicht erkannt, dass ich mich im Design Modus befinde und die Series, ChartAreas etc. sind auch nicht vorhanden. Anschließend werden die Propertys durchgegangen. In MaxAnzahlSeries erkennt er die von mir eingetragene Anzahl aus dem vorherigen aufrufen der Form.
    So, da er nicht erkennt, dass schon Serien vorhanden sind (Series.count=0 oder Series.FindbyName= nothing) versucht er diese Serien neu anzulegen, obwohl sie schon in der Form1.Deisgn.vb vorhanden sind. Deshalb jammert der Designer anschließend rum.

    Ignoriert man den Fehler und ändert die MaxAnzahlSeries, werden die bisherigen Series erkannt, gelöscht und neu angelegt. Sogar der DesignMode ist aktiv!
    Speichert man ab, lädt neu kommt der gleiche Fehler wieder .....
    Gruß von der KSE

    ks-entwicklung.de

    KSE schrieb:

    dass ich mich im Design Modus befinde
    So was:

    VB.NET-Quellcode

    1. If Me.DesignMode Then
    2. ' Designmodus
    3. End If
    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!

    KSE schrieb:

    Okay, ich habe es jetzt hin bekommen im Designmode zu debuggen.
    hast du nicht.

    Ich erinnere mich, dass ich die TestSolution innerhalb der Test-TestSolution startete, darin ein selbstgebasteltes Control auf ein Form zog, und mit Codestop und pipapo die Fehlermeldungen checken konnte, die im DesignModus auftraten.
    Genau das habe ich gemacht.
    Ich habe im MyProject -->Debuggen* Externes Programm starten: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv.exe eingetragen.
    Dann F5 und eine neu Instanz von VS wird geöffnet. Anschließend genau das Programm aufrufen. (In diesem Projekt befindet sich meine XChart Klasse und eine Form1 auf die ich das XChart gezogen habe)

    EDIT: Das Problem ist ich bekomme beim debuggen keine Fehlermeldung angezeigt ...
    Gruß von der KSE

    ks-entwicklung.de
    @KSE:: Mach doch mal Debug-Ausgaben rein (Debug.WriteLine(...)), lässt sich da was im Design verfolgen?
    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!

    KSE schrieb:

    wird nichts angezeigt...
    Bei mir schon:
    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!