Event "While Button is Pressed"

2.5k views Asked by At

I made Event for Grid in WPF C#.

The MouseMove Event.

I want to Trigger MouseMove event When mouse Left button is Pressed and Keep the Event even when mouse is Out of Grid Or even out of the main Window.

When Button is Pressed Keep the Mousemove event for the Grid All over the screen Until Button is Releasd.

consider this is Mouse move event Method for the Grid

    private void Grid_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed) // Only When Left button is Pressed.
        {
            // Perform operations And Keep it Until mouse Button is Released.
        }
    }

The Goal is to Rotate 3D model When User Hold Left button and to rotate Model while he is moving the mouse until button releases.

This is for To make the Program and Rotation Eeasier for the user. Especialy performing Long rotations cause mouse get out of the grid.

I tried to use while but it fails and you know its because of single threaded.

so the way im thinking is to somehow expand a new Grid all over the screen when button is pressed inside the original Grid and to keep it until release.

And of course Dummy Grid witch is Hidden.

1

There are 1 answers

3
Anton Sizikov On

What are you trying to do is to work with the stream of events. As far as I understand your flow supposed to be the following:

  1. Left mouse button pressed
  2. Mouse moved1 (rotate model)
  3. Mouse moved2 (rotate model)

    ...

    N. Left mouse up (stop rotation)

There is an interesting concept which is called Reactive Programming. http://rxwiki.wikidot.com/101samples

There is a library for C# (Reactive-Extensions)

Your code could look like this one:

// create event streams for mouse down/up/move using reflection
var mouseDown = from evt in Observable.FromEvent<MouseButtonEventArgs>(image, "MouseDown")
                select evt.EventArgs.GetPosition(this);
var mouseUp = from evt in Observable.FromEvent<MouseButtonEventArgs>(image, "MouseUp")
              select evt.EventArgs.GetPosition(this);
var mouseMove = from evt in Observable.FromEvent<MouseEventArgs>(image, "MouseMove")
                select evt.EventArgs.GetPosition(this);

// between mouse down and mouse up events
// keep taking pairs of mouse move events and return the change in X, Y positions
// from one mouse move event to the next as a new stream
var q = from start in mouseDown
        from pos in mouseMove.StartWith(start).TakeUntil(mouseUp)
                     .Let(mm => mm.Zip(mm.Skip(1), (prev, cur) =>
                          new { X = cur.X - prev.X, Y = cur.Y - prev.Y }))
        select pos;

// subscribe to the stream of position changes and modify the Canvas.Left and Canvas.Top
// property of the image to achieve drag and drop effect!
q.ObserveOnDispatcher().Subscribe(value =>
      {
          //rotate your model here. The new mouse coordinates
          //are stored in value object
          RotateModel(value.X, value.Y);
      });

Actually building a stream of mouse events is a very classical example of using RX.

http://theburningmonk.com/2010/02/linq-over-events-playing-with-the-rx-framework/

You can subscribe on this stream of events in the Windows constructor, so you don't depend on the Grid, and you don't have to draw fake Grid!

Some nice links to start with:

  1. The Rx Framework by example
  2. Rx. Introduction