2012-02-27 4 views
1

Я занят небольшим приложением, в котором хочу отображать информацию в месте расположения курсора, когда он поднимается над Canvas. Предложенный Canvas является обычным (унаследованным от Canvas), который предоставляет функциональность для добавления DrawingVisuals (как показано в основном в каждом учебном пособии по отображению большого количества геометрических фигур на холсте).Проблема с производительностью DrawingVisual после курсора при использовании события onMouseMove

Я хотел бы показать вертикальную линию и горизонтальную линию, а также локальные координаты (p в коде ниже), которые непосредственно получены из координат холста (v). В настоящий момент я обрабатываю эти объекты в позиции (0,0) и использую смещение во время события OnMouseMove для обновления своего местоположения.

Горизонтальные и вертикальные линии отображаются в DrawingVisual _cursor и местоположении в локальных y, z-координатах в _info.

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

Edit: я исследовал его немного дальше, и проблема, кажется, происходит, когда разрешение холста больше. Если это холст 600x400, то нет задержек, но когда он составляет около 1000x800, я получаю проблему с задержками при обжиге. Производительность также улучшается, если я использую привлеченные пользователем перекрестия вместо линий, которые имеют полную ширину/высоту холста.

+0

Как он ведет себя, когда вы установите [Transform] (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

+0

Спасибо за ваш быстрый ответ, но, к сожалению, нет улучшения с 'TranslateTransform' – Geoffrey

ответ

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

Большое спасибо. Ваш ответ в сочетании со мной, обнаружив, что разрешение экрана задействовано, решило мою проблему. В моем исходном объекте-курсоре рисовалась горизонтальная и вертикальная линии. Видимо (я мог ошибаться) ограничивающая рамка определяет, что WPF хочет перерисовать (или проверить наложение). Поэтому я исправил проблему, используя два объекта курсора, один для горизонтального и один для вертикальной линии. – Geoffrey