为签名控件提高面板OnMouseMove方法的性能

时间:2013-02-05 15:10:05

标签: c# .net winforms c#-2.0

我有一个Windows Mobile应用程序(C#,。Net framework 2),其代码库现在也用于在Windows 7和Windows 8上运行。我们为此应用程序编写的一个控件是一个涂鸦控件允许用户捕获签名。此控件在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));
}

上面代码中的_captureMouseCoordinates布尔成员变量是在'mousedown'事件处理程序上设置的。

我注意到,如果我在此方法中注释掉invalidate并且只在mouseup上失效,那么签名会更顺畅,但是在绘制时你不会看到签名。有没有人有任何想法如何让这个签名控件更好地执行,以便它产生的签名更顺畅,但仍然能够在绘制线条时向用户提供反馈。

1 个答案:

答案 0 :(得分:1)

我不知道_graphicsHandle在哪里 - 但你通常不应该保存Graphics对象。让所有渲染都在Invalidate()中。

创建两个集合:

List<Point> _currentStroke
List<List<Point>> _allStrokes

的MouseMove:

_currentStroke.Add(e.Location)

的MouseUp

   _allStrokes.Add(_currentStroke)

在每个OnPaint上

   foreach(var stroke in _allStrokes)
       {g.DrawLines(pen, stroke.ToArray());}
   if(_currentStroke.Count > 1)
       g.DrawLines(pen, _currentStroke)

(显然添加所有支持代码)。

您应该没有性能问题。