按下mousedown按钮时C#循环

时间:2011-10-10 11:51:35

标签: c# winforms mouseevent

我想在按下鼠标左键的同时使用循环:

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

我不能使用这个帖子的解决方案:
C# how to loop while mouse button is held down 因为我通过RS232数据发送并使用定时器,它自己的间隔不起作用。此主题的任何解决方案对我都不起作用。 它不能像这里一样工作:

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

此解决方案也不起作用:

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 main loop you care about.  Put this in your application
//This should go in its own thread
void runLoop() {
    while (isLooping) {
        //do stuff
    }
}

因为调用runLoop会阻塞该线程,因此MouseUp事件永远不会触发。

那么如何让它正常工作?

4 个答案:

答案 0 :(得分:2)

使用BackGroundWorker。适合您的问题。

将循环函数放入worker中,并在鼠标事件上启动/停止worker。

答案 1 :(得分:0)

如果使用定时器不起作用,则需要在不同的线程上发送数据,并从MouseUp处理程序发出该线程的信号。

答案 2 :(得分:0)

执行此操作的正确方法是将rs-232发送功能放入单独的线程中,以便UI保持响应,然后您可以在鼠标事件发生更改时启动和停止它。

此页面可能有用:

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

答案 3 :(得分:0)

这些场景实现起来非常复杂 - 请参阅处理程序和布尔变量以存储状态。

我建议使用Reactive Extensions

修改

它可能会略微过度设计(我不知道这是否是Elfoc想要实现的唯一场景)。在Rx中,您可以创建可观察的事件序列

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

使用LINQ-to-Rx查询和过滤事件

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

并使用Rx运算符进行组合 - 直到任何鼠标向上事件被提升为止所有位置而鼠标左键停止

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

最后,订阅可观察的职位序列并做你的事情

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

从代码here略微修改。