tags:

views:

49

answers:

1

Hi all,

I'm implementing a 'value under cursor' readout for chart contents. Currently I am achieving this using ReactiveExtensions and subscribing to the GetMouseMove event on my chart background Grid:

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

And that works fine. I can move my mouse around and I get my text block updated.

The problem is that the chart contents are being updated dynamically (moving across the screen). If I leave the mouse cursor stationary over the point, the contents beneath it change but (obviously) the readout is not updated.

I attempted to manually trigger the mouse move by setting the cursor position to itself whenever the data in the model was updated:

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

This did not trigger the callback. Setting the position to be (X-1, Y-1) DID trigger the callback, but if I immediately set the pixel back to the original location (a subsequent X+1,Y+1) this does NOT trigger the mousemove callback for either Position set.

I also tried manually setting the readoutTextBlock on notification of my model changed based on Mouse.GetPosition(m_PlotArea) but encountered threading issues (model is update in separate thread) and also hit-test issues with m_PlotArea.

Any suggestions?

+2  A: 

I think that is will be cleaner to use separate event source.

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

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

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

Now you can force event processing:

manualTrigger.OnNext(new Position(...)); 
desco
This is a nice clean way to amalgamate events.Its not exactly what I was after, but its a cleaner way than the hack I was implementing. Cheers
Rodney Thomson