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.
精彩评论