我有一个显示各种数据的图表。用户可以点击图表(第一次点击),一个框将绘制到鼠标移动的位置。在第二次单击时,所选区域将成为图表的新边界(放大)。
我通过在图表的绘图事件中绘制4行,并在每次鼠标移动以强制绘制事件时调用chart.invalidate来执行此操作。
它适用于少于1000个数据点,但通过它变得非常迟缓。我想知道是否有一种方法可以在每次移动鼠标时重新绘制图表而不重新绘制图表(因为我认为这是问题)
我也尝试使用自定义的“浮动线”,它覆盖了表单上的所有控件(包括图表),但我遇到了鬼线(想想:快速移动Windows XP窗口)。我认为这是不断移动线路位置的一个不可避免的错误。
感谢任何想法/想法。
重绘代码:
Private Sub Chart1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Chart1.Paint
Dim arbitraryPen As New Pen(Brushes.Black, 1)
e.Graphics.DrawLine(arbitraryPen, point1.x, point1.y, point2.x, point1.y)
e.Graphics.DrawLine(arbitraryPen, point1.x, point1.y, point1.x, point2.y)
e.Graphics.DrawLine(arbitraryPen, point1.x, point2.y, point2.x, point2.y)
e.Graphics.DrawLine(arbitraryPen, point2.x, point1.y, point2.x, point2.y)
arbitraryPen.Dispose()
End Sub
答案 0 :(得分:1)
我之前遇到过这种情况。我的解决方案是在MouseDown
事件(包含图表的容器)中创建图表的图像,并将其添加到图表顶部的窗口中。在MouseMove
事件中,我按照您的方式画线 - 但没有调用chart.Invalidate()
。在MouseUp
事件中,我删除了图表的图像,并执行了缩放。这是一种黑客行为,但在这些图表中处理大量数据时,我发现了很多事情。
用于创建图像并显示图像的ETA代码
private void CreateImagePanel()
{
Bitmap image = new Bitmap(Chart.Width, Chart.Height);
Chart.DrawToBitmap(image, Chart.ClientRectangle);
Panel panel = new Panel();
SetDoubleBuffered(panel);
panel.BackgroundImage = image;
panel.Width = Chart.Width;
panel.Height = Chart.Height;
panel.Location = Chart.Location;
panel.Paint += PaintRectangle;
panel.Name = "imagePanel";
_imagePanel = panel;
Chart.Parent.Controls.Add(panel);
panel.BringToFront();
}
_imagePanel
是该类的私有成员,因此可以轻松删除该面板。 SetDoubleBuffered
是另一种私有方法,可以很容易地修改为扩展方法:
private void SetDoubleBuffered(Control c)
{
if (SystemInformation.TerminalServerSession) return;
PropertyInfo property = typeof(Control).
GetProperty("DoubleBuffered", BindingFlags.NonPublic | BindingFlags.Instance);
property.SetValue(c, true, null);
}
处理图像面板的PaintRectangle
事件以仅绘制选择矩形。在MouseMove
事件中,图像面板为Invalidated
,强制重绘面板,从而重绘矩形。私有属性用于存储矩形的边界。