C# 改进签名控件的panel OnMouseMove方法的性能

C# 改进签名控件的panel OnMouseMove方法的性能,c#,.net,winforms,c#-2.0,C#,.net,Winforms,C# 2.0,我有一个Windows Mobile应用程序(C#,.Net framework 2),其代码库现在也被用于在Windows 7和Windows 8上运行。我们为这个应用程序编写的一个控件是scribble控件,它允许用户捕获签名。此控件在Windows Mobile上正常工作,可以很好地用于捕获签名。然而,在Windows上,面板控件的OnMouseMove覆盖方法太慢,或者调用频率太低,签名变得非常“块状”。因此,例如,如果您尝试捕获一个圆,在Windows Mobile上您会得到一个合理的

我有一个Windows Mobile应用程序(C#,.Net framework 2),其代码库现在也被用于在Windows 7和Windows 8上运行。我们为这个应用程序编写的一个控件是scribble控件,它允许用户捕获签名。此控件在Windows Mobile上正常工作,可以很好地用于捕获签名。然而,在Windows上,面板控件的
OnMouseMove
覆盖方法太慢,或者调用频率太低,签名变得非常“块状”。因此,例如,如果您尝试捕获一个圆,在Windows Mobile上您会得到一个合理的圆,但在Windows上您最终会得到一个正方形,因为调用
mousemove
的频率不够高。以下是面板的
OnMouseMove
覆盖方法:

protected override void OnMouseMove(MouseEventArgs e)
{
    base.OnMouseMove(e);
    if (!_captureMouseCoordinates) { return; }
    LineToDraw line = new LineToDraw();
    line.StartX = _lastMouseCoordinates.X;
    line.StartY = _lastMouseCoordinates.Y;
    line.EndX = e.X;
    line.EndY = e.Y;
    _points.Add(line);
    _graphicsHandle.DrawLine(_scribblePen, line.StartX, line.StartY, line.EndX, line.EndY);            
    // Refresh rectangle for the line drawn
    Point leftCorner = new Point();
    Size rectangleSize = new Size();
    // Case 1: line down, right
    if (line.StartX <= line.EndX && line.StartY <= line.EndY) 
    {
        leftCorner.X = line.StartX;
        leftCorner.Y = line.StartY;
    }
    // Case 2: Line up, right
    if (line.StartX <= line.EndX && line.StartY >= line.EndY) 
    {
         leftCorner.X = line.StartX;
         leftCorner.Y = line.EndY;
    }
    // Case 3: Line up, left
    if (line.StartX >= line.EndX && line.StartY >= line.EndY) 
    {
        leftCorner.X = line.EndX;
        leftCorner.Y = line.EndY;
    }
    // Case 4: Line down, left
    if (line.StartX >= line.EndX && line.StartY <= line.EndY) 
    {
        leftCorner.X = line.EndX;
        leftCorner.Y = line.StartY;
    }
    rectangleSize.Height = Math.Abs(line.EndY-line.StartY)+1;
    rectangleSize.Width = Math.Abs(line.EndX-line.StartX)+1;
    // save last mouse co-ordinates
    _lastMouseCoordinates.X = line.EndX;
    _lastMouseCoordinates.Y = line.EndY;
    Invalidate(new Rectangle(leftCorner.X,leftCorner.Y, rectangleSize.Width, rectangleSize.Height));
}
mouseMove上的受保护覆盖无效(MouseEventArgs e)
{
基地移动(e);
if(!\u captureMouseCoordinates){return;}
LineToDraw line=新LineToDraw();
line.StartX=_lastMouseCoordinates.X;
line.StartY=_上次鼠标坐标.Y;
line.EndX=e.X;
line.EndY=e.Y;
_点。添加(行);
_graphicsHandle.DrawLine(_scribblePen,line.StartX,line.StartY,line.EndX,line.EndY);
//刷新绘制的直线的矩形
点左角=新点();
大小矩形大小=新大小();
//案例1:排队,对吗
如果(line.StartX=line.EndY)
{
leftCorner.X=line.EndX;
leftCorner.Y=line.EndY;
}
//案例4:线路向下,左侧

如果(line.StartX>=line.EndX&&line.StartY我不知道_graphicsHandle在哪里-但您通常不应该保存图形对象。让所有渲染都在Invalidate()中

创建两个集合:

List<Point> _currentStroke
List<List<Point>> _allStrokes
鼠标

   _allStrokes.Add(_currentStroke)
在每一个油漆上

   foreach(var stroke in _allStrokes)
       {g.DrawLines(pen, stroke.ToArray());}
   if(_currentStroke.Count > 1)
       g.DrawLines(pen, _currentStroke)
(显然要添加所有支持代码)


您应该没有性能问题。

我不知道graphicsHandle在哪里-但是您通常不应该保存图形对象。让所有渲染都在Invalidate()中

创建两个集合:

List<Point> _currentStroke
List<List<Point>> _allStrokes
鼠标

   _allStrokes.Add(_currentStroke)
在每一个油漆上

   foreach(var stroke in _allStrokes)
       {g.DrawLines(pen, stroke.ToArray());}
   if(_currentStroke.Count > 1)
       g.DrawLines(pen, _currentStroke)
(显然要添加所有支持代码)


您应该没有性能问题。

也许每隔一次尝试使用切换变量调用invalidate?也许每隔一次尝试使用切换变量调用invalidate?谢谢John的回答。您对图形句柄的了解非常到位,这确实是问题的核心。阅读您的回答后,发现有问题正在刷新图像的“OnPaint”重写。这就是导致scribble控件运行如此缓慢的原因。我现在已重新构造代码,使其不使用图像,并且运行速度更快。签名实际上现在看起来像签名!;)感谢您的帮助。感谢John的回答。您对图形句柄的了解非常到位,这确实是问题的核心。在阅读您的回答后,发现有一个“OnPaint”覆盖正在刷新图像。这就是导致scribble控件运行如此缓慢的原因。我现在已将代码重新构造为不使用图像和它运行得更快。签名实际上现在看起来像签名!;)谢谢你的帮助。