【问题标题】:Improve the performance of a panel OnMouseMove method for a signature control改进签名控件的面板 OnMouseMove 方法的性能
【发布时间】:2013-02-06 01:34:50
【问题描述】:

我有一个 Windows Mobile 应用程序(C#、.Net 框架 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”事件处理程序上设置的。

我注意到,如果我在此方法中注释掉无效,并且仅在 mouseup 上无效,那么签名会更加平滑,但是在绘制签名时您看不到签名。有没有人知道如何让这个签名控件表现得更好,以便它产生的签名更平滑,但仍然能够在绘制线条时向用户提供反馈。

【问题讨论】:

  • 也许尝试使用切换变量每隔一段时间调用一次无效?

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


【解决方案1】:

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

创建两个集合:

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

鼠标移动:

_currentStroke.Add(e.Location)

鼠标移动

   _allStrokes.Add(_currentStroke)

在每个 OnPaint 上

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

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

您应该没有性能问题。

【讨论】:

  • 感谢约翰的回答。您对图形句柄很了解,这确实是问题的核心。阅读您的答案后,发现有一个“OnPaint”覆盖正在刷新图像。这就是导致涂鸦控件运行如此缓慢的原因。我现在已经重组了代码以不使用图像,并且它的运行速度快得多。签名现在实际上看起来像签名! ;) 感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-06
相关资源
最近更新 更多