2012-02-27 3 views
1

私はカーソルの位置に情報を表示したいときに忙しいです。問題のキャンバスは、キャンバスから大量の幾何学的図形を表示する際の基本的なチュートリアルに示すように、DrawingVisualを追加する機能を提供するカスタムキャンバスです。onMouseMoveイベントを使用しているときにカーソルに続くDrawingVisualのパフォーマンス問題

キャンバスの座標(v)から直接派生した垂直線と水平線、およびローカル座標(下のコードではp)を表示したいとします。現時点では、これらのオブジェクトを位置(0,0)にレンダリングし、OnMouseMoveイベント中にオフセットを使用して位置を更新します。

水平線と垂直線はDrawingVisual_cursorに、ローカルy座標は_infoのz座標に表示されます。 MouseMoveイベントを使用して

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; 
    } 

オーバーヘッドの多くを作成しているようだと、私はすぐにマウスを移動するとき、私はマウスの動きを追跡する問題があることがわかります。

誰も同じ効果を作り出すより良い方法をお勧めしますか?

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

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

+0

がどのように振る舞うん[変換](http://msdn.microsoft.com/en-us/library/system.windows.media.containervisual:

は、ここでは、コードです。 transform.aspx)プロパティを[TranslateTransform](http://msdn.microsoft.com/en-us/library/system.windows.media.translatetransform.aspx)に変更する必要があります。 – Clemens

+0

ありがとうございましたが、残念ながら 'TranslateTransform'では改善がありません – Geoffrey

答えて

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; 
    } 
} 
+0

ありがとうございました。画面の解像度が関与していることを発見した私と一緒にあなたの返答が私の問題を解決しました。オリジナルの_cursorオブジェクトには、水平線と垂直線の両方が描画されていました。明らかに(私は間違っている可能性があります)、WPFが再描画したい(またはオーバーレイを確認する)かどうかは、境界ボックスによって決まります。だから私は2つのカーソルオブジェクトを使用して問題を解決しました。一つは水平、もう一つは垂直ラインです。 – Geoffrey

関連する問題