使用onMouseMove事件时,DrawingVisual跟随光标的性能问题

时间:2012-02-27 13:43:16

标签: c# wpf user-interface onmousemove

我正忙于一个小应用程序,我希望在光标悬停在Canvas上时在光标位置显示信息。有问题的Canvas是一个自定义的Canvas(继承自Canvas),它提供了添加DrawingVisuals的功能(基本上每个教程都显示在画布上显示大量的几何形状)。

我想显示垂直线和水平线以及直接从画布坐标(v)导出的局部坐标(下面的代码中的p)。目前我正在位置(0,0)渲染这些对象,并在OnMouseMove事件期间使用偏移来更新它们的位置。

水平线和垂直线在DrawingVisual _cursor中呈现,位置在_info中的局部y,z坐标中。

private void oCanvas_MouseMove(object sender, MouseEventArgs e)
    {
        #region 1. Get location data

        System.Windows.Vector v = (System.Windows.Vector)e.GetPosition(oCanvas);
        // point in YZ coordinates
        BSMath.DoubleXY p = new BSMath.DoubleXY();
        p.X = (oCanvas.OriginY - v.Y) / oCanvas.ZoomFactor;
        p.Y = (oCanvas.OriginX - v.X) / oCanvas.ZoomFactor;

        #endregion

        #region 2. Update cursor and info

        if (oSettings.ShowInformation)
        {
            _info.Info = p.X.ToString("0.0") + "  |  " + p.Y.ToString("0.0");
            _info.Render(0, 0);
            _info.Visual.Offset = v;
        }            

        // move cursor
        _cursor.Visual.Offset = v;
    }

使用mousemove事件似乎会产生大量开销,我可以看到当我快速移动鼠标时跟踪鼠标移动存在问题。

有人可以推荐更好的方法来创造相同的效果吗?

example http://www.iccg.be/test/images/canvas.jpg

修改 我进一步调查了一下,当画布的分辨率更大时,似乎会出现问题。如果它是一个600x400的画布,那么没有延迟,但是当它大约是1000x800时,我会遇到延迟问题。如果我使用用户绘制的十字准线而不是具有画布的整个宽度/高度的线条,性能也会提高。

1 个答案:

答案 0 :(得分:1)

我最近已经构建了类似的东西并且没有任何性能问题。 通过直接在画布上添加内容,这是非常简单的方法。 绘制的项目位于鼠标位置画布后面的第二个画布中。两者都驻留在网格中。 这肯定不是解决这个问题最复杂的方法,但对我来说效果很好。

以下是代码:

private Point _previous;
private Point _current;

private Line _xLine;
private Line _yLine;
private TextBlock _displayTextBlock;

private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
  _current = e.GetPosition(myCanvas);

  if (_previous != _current)
  {
    if (_xLine == null)
    {
      _xLine = new Line() {X1 = 0, X2 = myCanvas.ActualWidth, Stroke = new SolidColorBrush(Colors.Black)};
      _yLine = new Line() {Y1 = 0, Y2 = myCanvas.ActualHeight, Stroke = new SolidColorBrush(Colors.Black)};
      _displayTextBlock = new TextBlock();

      myCanvas.Children.Add(_xLine);
      myCanvas.Children.Add(_yLine);
      myCanvas.Children.Add(_displayTextBlock);
    }

    _displayTextBlock.SetValue(Canvas.TopProperty, _current.Y);
    _displayTextBlock.SetValue(Canvas.LeftProperty, _current.X);
    _displayTextBlock.Text = _current.X.ToString() + " | " + _current.Y.ToString();
    _xLine.Y1 = _current.Y;
    _xLine.Y2 = _current.Y;
    _yLine.X1 = _current.X;
    _yLine.X2 = _current.X;

    _previous = _current;
  }
}