开发者

C# loop while mousedown button pressed

开发者 https://www.devze.com 2023-04-12 12:05 出处:网络
I\'d like to use loop while left mousebutton is pressed: private void Loop_MouseDown(object sender, MouseEventArgs e)

I'd like to use loop while left mousebutton is pressed:

  private void Loop_MouseDown(object sender, MouseEventArgs e)
        {
            while (e.Button==MouseButtons.Left)
            {
            //Loop
            }
        }

I can't use solution from this thread:

C# how to loop while mouse button is held down because I'm sending via RS232 data and using timer with it's own interval doesn't work. Also any solution from this topic doesn't work for me. It can't also work one like here:

 if (e.Button == MouseButtons.Left)
    {
        //loop
    }

This solution also doesn't work:

bool isLooping = false;

//on mouse down
private void myControl_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) {
    isLooping = true;
    runLoop();
}

//on mouse up event
private void myControl_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) {
    isLooping = false;
}

//This is the mai开发者_运维问答n loop you care about.  Put this in your application
//This should go in its own thread
void runLoop() {
    while (isLooping) {
        //do stuff
    }
}

because calling runLoop would block the thread, and so the MouseUp event would never fire.

So how to make it work correctly?


Use a BackGroundWorker. Perfect for your problem.

Put the loop function in the worker and start / stop the worker on mouse events.


If using a timer won't work, you'll need to send the data on a different thread, and signal that thread from the MouseUp handler.


The correct way to do this would be to put the rs-232 send function into a separate thread so the UI will remain responsive, then you can start and stop it when the mouse events change.

This page might be useful:

http://www.yoda.arachsys.com/csharp/threads/winforms.shtml


These scenarios are very complicated to implement - see your handlers and boolean variables for storing the state.

I would suggest to use Reactive Extensions.

Edit:

It will probably be slightly over-engineered (I don't know if this is the only scenario Elfoc wants to implement). In Rx you can create observable sequence of events

var mouseDown = Observable.FromEvent<MouseButtonEventArgs>(source, "MouseDown"); 
var mouseUp = Observable.FromEvent<MouseButtonEventArgs>(image, "MouseUp"); 
var mouseMove = from evt in Observable.FromEvent<MouseEventArgs>(image, "MouseMove") 
  select evt.EventArgs.GetPosition(this);

use LINQ-to-Rx to query and filter the events

var leftMouseDown = from evt in mouseDown 
  where evt.LeftButton == MouseButtonState.Pressed
  select evt; 

and compose it using Rx operators - until any mouse up event is raised take all the positions while left mouse is down

var q = from position in leftMouseDown  
    from pos in mouseMove.Until(mouseUp) 
    select new { X = pos.X - imageOffset.X, Y = pos.Y - imageOffset.Y }; 

Finally, subscribe to the observable sequence of positions and do your stuff

q.Subsribe(value => { ... });

Slightly modified from the code here.

0

精彩评论

暂无评论...
验证码 换一张
取 消