2012-02-27 54 views
1

我忙於使用一個小應用程序,在該應用程序中,當光標位於Canvas上方時,在光標位置顯示信息。所討論的Canvas是一個自定義的(從Canvas繼承的),它提供了添加DrawingVisuals的功能(基本上每個教程都展示了大量的幾何圖形)。在使用onMouseMove事件時DrawingVisual跟隨光標的性能問題

我想顯示垂直線和水平線,以及直接從畫布座標(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; 
    } 

使用鼠標移動事件似乎造就了不少的開銷,我可以看到,有跟蹤鼠標移動的問題時,我快速移動鼠標。

任何人都可以推薦一個更好的方式來創建相同的效果?

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)而不是使用Offset? – Clemens 2012-02-27 15:13:36

+0

感謝您的快速回復,但不幸的是'TranslateTransform'沒有任何改進。 – Geoffrey 2012-02-27 16:13:58

回答

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

非常感謝。您的回覆與我結合發現屏幕分辨率涉及解決了我的問題。在我最初的_cursor對象中,繪製了水平和垂直線。顯然(我可能是錯的)邊界框確定WPF想要重繪(或檢查覆蓋)。所以我通過使用兩個光標對象來解決問題,一個用於水平線,另一個用於垂直線。 – Geoffrey 2012-02-28 13:50:28