解決方案,聯想的右對接(見下文底部對接):它的工作,我也有每個系列線ChartDashStyle設置,以及指定一個傳奇的字體和大小。我修改了上面的代碼並調整了相當多的像素調整,以便將新圖例向上移動,並根據圖例的字體大小添加行之間的間距。我還添加了一些邏輯語句將ChartDashStyle轉換爲GDI + DashStyle。
在您動態創建例如Chart1對象,並處理所有代碼來填充系列等,所有你需要做的調用圖表的PostPaint事件是在所有圖表處理代碼末尾添加以下代碼:
Dim Chart1 As New Chart
Chart1.Invalidate()
Chart1.ChartAreas.Clear()
Chart1.Legends.Clear()
Chart1.Series.Clear()
.
.
(fill series datapoints, legend, titles, etc)
.
.
AddHandler Chart1.PostPaint, AddressOf Chart1_PostPaint
的繪畫後,PostPaint事件將觸發,然後調用方法(下面的子例程)用彩色線條重新創建圖例,並根據每個系列的相同屬性使用合適的粗細和虛線樣式。
(有不需要是在子程序的定義的端部的Handles...
)
Private Sub Chart1_PostPaint(ByVal sender As Object, ByVal e As ChartPaintEventArgs)
If TypeOf e.ChartElement Is Legend Then
Dim c As Chart = CType(sender, Chart)
Dim g As Graphics = e.ChartGraphics.Graphics
'The legend
Dim l As Legend = c.Legends(0)
'Absolute dimensions of the legend (New legend will be based on this.. won't be exact.)
Dim pos As RectangleF = e.ChartGraphics.GetAbsoluteRectangle(l.Position.ToRectangleF)
'Absolute dimensions of one legend "cell"
Dim itemHeight As Single = pos.Height/c.Series.Count + 30
Dim itemWidth As Single = pos.Width/2
'Padding between line and text (horizontal) and each item (vertical)
Dim horizontalPadding As Single = 10
Dim verticalPadding As Single = l.Font.Size
Dim legendFont As Font = l.Font
'Draw a white box on top of the default legend to hide it
g.FillRectangle(Brushes.White, pos)
For i As Integer = 0 To c.Series.Count - 1
Dim s As Series = c.Series(i)
Dim p As New Pen(s.Color, CSng(Math.Min(s.BorderWidth, itemHeight))) 'Line no thicker than the item height.
Dim ds As ChartDashStyle = s.BorderDashStyle
'Line
Dim posY As Single = CSng(pos.Y + (verticalPadding * i + itemHeight * i + itemHeight/2)) - (c.Series.Count + 2) * verticalPadding
Dim startPoint As PointF = New PointF(pos.X, posY)
Dim endPoint As PointF = New PointF(CSng(pos.X + itemWidth), posY)
p.DashStyle = ds
If ds = ChartDashStyle.Solid Then
p.DashStyle = DashStyle.Solid
End If
If ds = ChartDashStyle.Dash Then
p.DashStyle = DashStyle.Dash
End If
If ds = ChartDashStyle.DashDot Then
p.DashStyle = DashStyle.DashDot
End If
If ds = ChartDashStyle.DashDotDot Then
p.DashStyle = DashStyle.DashDotDot
End If
g.DrawLine(p, startPoint, endPoint)
'Text
posY = CSng(pos.Y + verticalPadding * i + itemHeight * i) - (c.Series.Count + 2) * verticalPadding
startPoint = New PointF(CSng(pos.X + itemWidth), posY)
g.DrawString(s.Name, legendFont, Brushes.Black, startPoint.X + horizontalPadding + 5, startPoint.Y - 5)
Next
End If
End Sub
下面是一個例子得到說明:
圖例的底部對接,將碼有結果如下:
Private Sub Chart1_PostPaint(ByVal sender As Object, ByVal e As ChartPaintEventArgs)
If TypeOf e.ChartElement Is Legend Then
Dim c As Chart = CType(sender, Chart)
Dim g As Graphics = e.ChartGraphics.Graphics
'The legend
Dim l As Legend = c.Legends(0)
'Absolute dimensions of the legend (New legend will be based on this.. won't be exact.)
Dim pos As RectangleF = e.ChartGraphics.GetAbsoluteRectangle(l.Position.ToRectangleF)
Dim numrows As Single = Math.Max(Math.Floor(pos.Height/l.Font.Height), 1)
'Absolute dimensions of one legend "cell"
Dim itemHeight As Single = pos.Height/numrows
Dim numcols As Integer
If c.Series.Count = 1 Then numcols = 1
If c.Series.Count = 2 Then numcols = 2
If c.Series.Count = 4 Then numcols = 4
If c.Series.Count = 3 OrElse c.Series.Count > 4 Then numcols = 3
Dim itemWidth As Single = pos.Width
If c.Series.Count = 1 Then itemWidth = pos.Width
If c.Series.Count = 2 Then itemWidth = pos.Width/2
If c.Series.Count = 4 Then itemWidth = pos.Width/4
If c.Series.Count = 3 OrElse c.Series.Count > 4 Then itemWidth = pos.Width/3
itemWidth *= 0.9
'Padding between line and text (horizontal) and each item (vertical)
Dim horizontalPadding As Single = 10
Dim verticalPadding As Single = 1
Dim legendFont As Font = l.Font
'Dim legendFont As New Font("Arial", 10)
'Draw a white box on top of the default legend to hide it
g.FillRectangle(Brushes.White, pos)
For i As Integer = 0 To c.Series.Count - 1
Dim s As Series = c.Series(i)
Dim p As New Pen(s.Color, CSng(Math.Min(s.BorderWidth, itemHeight))) 'Line no thicker than the item height.
Dim ds As ChartDashStyle = s.BorderDashStyle
If ds = ChartDashStyle.Solid Then
p.DashStyle = DashStyle.Solid
End If
If ds = ChartDashStyle.Dash Then
p.DashStyle = DashStyle.Dash
End If
If ds = ChartDashStyle.DashDot Then
p.DashStyle = DashStyle.DashDot
End If
If ds = ChartDashStyle.DashDotDot Then
p.DashStyle = DashStyle.DashDotDot
End If
Dim row As Integer
If c.Series.Count = 4 Then row = Math.Ceiling((i + 1)/4)
If c.Series.Count <> 4 Then row = Math.Ceiling((i + 1)/3)
Dim col As Integer
If c.Series.Count = 1 Then col = 0
If c.Series.Count = 2 Then col = i Mod 2
If c.Series.Count = 4 Then col = i Mod 4
If c.Series.Count = 3 OrElse c.Series.Count > 4 Then col = i Mod 3
'Line
Dim posx As Single = CSng((pos.X + (horizontalPadding + itemWidth * (col - 1)) + itemWidth/2))
Dim posY As Single = CSng((pos.Y + (verticalPadding + itemHeight * (row - 1)) + itemHeight/2))
Dim startPoint As PointF = New PointF(posx + itemWidth * 0.75, posY)
Dim endPoint As PointF = New PointF(CSng(posx + itemWidth), posY)
g.DrawLine(p, startPoint, endPoint)
'Text
posx = posx + itemWidth
startPoint = New PointF(posx, posY - l.Font.Height/2)
g.DrawString(s.Name, legendFont, Brushes.Black, startPoint.X + horizontalPadding, startPoint.Y)
Next
End If
End Sub
下面是底部對接時的結果示例使用:
嘗試過,但因爲是動態創建的圖表手柄Chart1.PostPaint事件拋出異常。這不是一個簡單的按鈕,因此您需要在創建動態創建的Chart時建議如何在代碼中運行代碼。必須有一個解決方法(?) – wrtsvkrfm