Ich weiß, dass dies eine ziemlich populäre Frage ist, aber keine der Lösungen, die ich gefunden habe, hat für mich funktioniert.Wie man die Steuerelemente während MouseMove Event flackert Event
Hintergrund: Ich habe ein Windows Forms-Projekt in VS2015, das Daten aus Textdateien liest und die Daten als mehrere Serien in einem Liniendiagramm darstellt. Das Chart.MouseMove-Ereignis findet den Punkt, der der Maus am nächsten ist, und zeichnet einen Kreis darum. Der Kreis wird im Fall Chart_Paint gezogen
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
Wenn über die Karte die Maus zu bewegen, zufällige Kontrollen flackern, auf das dann wieder sehr ärgerlich ist. Ich habe den folgenden MouseMove-Ereigniscode veröffentlicht.
Mögliche Lösungen Ich habe versucht:
- Einschalten der DoubleBuffered Eigenschaft des Formulars, die nichts
- Mit dem Me.Invalidate tut() und Me.Update() -Methode, die nicht bewegt sich der Kreis
- die Chart.Invalidate Verwendung() und Chart.Update() -Methode, die funktioniert, ist aber sehr langsam
- den folgenden Code zu meiner Form_Load Routine hinzufügen, die nichts
Jede mögliche Hilfe bei diesem stark
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
Me.SetStyle(ControlStyles.DoubleBuffer, True)
Me.SetStyle(ControlStyles.UserPaint, True)
Mouseereigniscode würde geschätzt:
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
Ich bin mir nicht sicher, warum Sie das Mousemove-Ereignis dafür verwenden - es wird die ganze Zeit feuern. Haben Sie versucht, einen Timer zurückzusetzen, während sich die Maus bewegt, und dann den Kreis zu zeichnen, wenn er anhält? – peterG
Sie können besser bedient werden, indem Sie eine Diagrammanmerkung oder ein DataPoint-Label anstelle eines benutzerdefinierten Malvorgangs verwenden. Wenn Sie ein Beispiel benötigen, kann ich eins zur Verfügung stellen. – TnTinMn
@peterG Danke für den Vorschlag! Ich hatte keinen Timer ausprobiert, habe aber jetzt und es macht nur das Flackern etwas seltener – JerryT