我知道这是一个非常受欢迎的问题,但我发现的解决方案都没有对我有用。
背景:我在VS2015中有一个Windows窗体项目,它从文本文件中读取数据,并在折线图上将数据绘制为多个系列。 Chart.MouseMove事件找到离鼠标最近的点并在其周围绘制一个圆。圆圈在Chart_Paint事件中绘制
Private Sub crtLogView(sender As Object,e As PaintEventArgs) Handles crtLogView.Paint
Dim whitePen as New Pne(Color.White,2)
e.Graphics.DrawEllipse(whitePen,cir) '//cir is a Public Rectangle
End Sub
在图表上移动鼠标时,随机控件会闪烁然后重新开启,这非常烦人。我在下面发布了MouseMove事件代码。
我尝试过的潜在解决方案:
非常感谢任何帮助
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
Me.SetStyle(ControlStyles.DoubleBuffer, True)
Me.SetStyle(ControlStyles.UserPaint, True)
MouseMove事件代码:
Private Sub crtLogView_MouseMove(sender As Object, e As MouseEventArgs) Handles crtLogView.MouseMove
'//Show data for closest point to cursor & draw circle around point
Dim hResult As HitTestResult = crtLogView.HitTest(e.X, e.Y)
Dim srsNam As String = ""
Dim mouseY As Single
Dim pntDist As Double = 0
Dim pntX As Single
Dim pntY As Single
Dim mouseX As Single
On Error GoTo ErrTrap
'//Get X-Axis Position as integer
mouseX = Int(hResult.ChartArea.AxisX.PixelPositionToValue(e.X))
'// Set time value
lblTime.Text = String.Format("{0:n2}", hResult.ChartArea.AxisX.PixelPositionToValue(e.X) / 160)
'//Get Y-Axis Position
mouseY = hResult.ChartArea.AxisY.PixelPositionToValue(e.Y)
'//Get distance from mouse to point on Series(0)
pntDist = Math.Abs(crtLogView.Series(0).Points(mouseX).YValues(0) - mouseY)
srsNam = crtLogView.Series(0).Name '//1st series name
'//Find closest series
For i As Integer = 1 To crtLogView.Series.Count - 1
If Math.Abs(crtLogView.Series(i).Points(mouseX).YValues(0) - mouseY) < pntDist Then
pntDist = Math.Abs(crtLogView.Series(i).Points(mouseX).YValues(0) - mouseY)
srsNam = crtLogView.Series(i).Name
End If
Next
'//Set Top/Left values for circle
pntY = crtLogView.ChartAreas(0).AxisY.ValueToPixelPosition(crtLogView.Series(srsNam).Points(mouseX).YValues(0)) - 4
pntX = crtLogView.ChartAreas(0).AxisX.ValueToPixelPosition(Val(mouseX)) - 4
'//Move circle to closest point
cir.Location = New Point(pntX, pntY)
'//Refresh the form to move the circle
'//This works, but takes 2+ seconds to take effect
'crtLogView.Invalidate()
'crtLogView.Update()
'//This does not work
'Me.Invalidate()
'Me.Update()
'//This works, but randomly makes other controls flash/flicker
Me.Refresh()
ErrTrap:
End Sub
答案 0 :(得分:0)
在评论中,我提供了一个使用图表注释或数据点标签的示例,作为在鼠标光标下的点周围自定义绘制圆圈的替代方法,并将其包含在下面的代码中。但是,我意识到DataPoint Marker应该提供OP正在寻找的功能,并且可能是正确的解决方案。因此,该选项也包括在内。
注释是图表级图形,其中 - DataPoint Label和DataPoint Marker顾名思义与各个DataPoints相关联。可以使用正确的注释大小,因为它们的大小被指定为图表区域维度的百分比。此示例不会尝试根据当前图表大小调整注释的大小。
以下代码示例适用于WinForm。在VS中,向WinForm项目添加一个新类,并用此替换自动生成的代码。将此表单设置为启动表单。
{{1}}