1

私は小さなアプリケーションで忙しく、カーソルが 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 イベントを使用すると、多くのオーバーヘッドが発生するようで、マウスをすばやく動かすと、マウスの動きを追跡する際に問題が発生することがわかります。

同じ効果を生み出すためのより良い方法を推奨できる人はいますか?

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

編集: もう少し調査したところ、キャンバスの解像度が大きい場合に問題が発生するようです。600x400 のキャンバスの場合、遅延はありませんが、1000x800 前後の場合、フーバー時に遅延の問題が発生します。キャンバスの全幅/高さを持つ線の代わりにユーザーが描いた十字線を使用すると、パフォーマンスも向上します。

4

1 に答える 1

1

最近、似たようなものを作成しましたが、パフォーマンスの問題はありません。キャンバスに直接コンテンツを追加することで、非常に簡単な方法でした。描画されたアイテムは、マウス位置キャンバスの後ろの2番目のキャンバスにあります。どちらもグリッドに存在します。これは確かにこれを解決するための最も洗練された方法ではありませんが、私にとっては非常にうまく機能します。

コードは次のとおりです。

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;
  }
}
于 2012-02-28T09:03:36.960 に答える