Как вручную вызвать событие MouseMove для стационарной мыши - PullRequest
3 голосов
/ 27 августа 2010

Я реализую «значение под курсором» для отображения содержимого диаграммы. В настоящее время я достигаю этого с помощью ReactiveExtensions и подписываюсь на событие GetMouseMove на фоне моего графика. Сетка:

private void SetupMouseover( Grid plotArea)
{
    var mouseMove = from mo in plotArea.GetMouseMove()
                        select new
                        {
                            CurrentPos = mo.EventArgs.GetPosition( plotArea )
                        };

    mouseMove.Subscribe(
        item =>
        {
            // Update the readout contents
            readoutTextBlock.Text = PositionToReadoutValue(item.CurrentPos);
        }
    );
}

И это прекрасно работает. Я могу двигать мышью и обновлять свой текстовый блок.

Проблема в том, что содержимое диаграммы обновляется динамически (перемещаясь по экрану). Если я оставлю курсор мыши неподвижным над точкой, содержимое под ней изменится, но (очевидно) показания не обновятся.

Я попытался вручную запустить движение мыши, установив позицию курсора на себя каждый раз, когда данные в модели обновлялись:

private void MoveCursor()
{
    // move the mouse cursor 0 pixels
    System.Windows.Forms.Cursor.Position = new System.Drawing.Point(System.Windows.Forms.Cursor.Position.X, 
                                                                    System.Windows.Forms.Cursor.Position.Y);    
}

Это не вызвало обратный вызов. Установка положения в (X-1, Y-1) DID запускает обратный вызов, но если я немедленно верну пиксель в исходное положение (последующие X + 1, Y + 1), это НЕ вызовет обратный вызов mousemove для либо Позиция установлена.

Я также пытался вручную установить readoutTextBlock при уведомлении об изменении моей модели на основе Mouse.GetPosition (m_PlotArea), но столкнулся с проблемами потоков (модель обновляется в отдельном потоке), а также с проблемами проверки нажатия с m_PlotArea.

Есть предложения?

1 Ответ

2 голосов
/ 27 августа 2010

Я думаю, что будет чище использовать отдельный источник событий.

IObservable<Position> mouseMove = GetMouseMove(); // stream of MouseMove events

IObservable<Position> manualTrigger = new Subject<Position>();

var positionChange = mouseMove.Merge(manualTrigger);
positionChange.Subscribe(pos => ...);

Теперь вы можете форсировать обработку событий:

manualTrigger.OnNext(new Position(...)); 
...