【问题标题】:C# loop while mousedown button pressed按下 mousedown 按钮时 C# 循环
【发布时间】:2011-10-10 20:32:23
【问题描述】:

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

  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 事件永远不会触发。

那么如何让它正常工作呢?

【问题讨论】:

  • 你有没有考虑过使用 API 来获取鼠标按键的当前状态?

标签: c# winforms mouseevent


【解决方案1】:

使用 BackGroundWorker。完美解决您的问题。

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

【讨论】:

  • 当你说“停止”时,你的意思是“cancel”吗?
  • sry 表示 RunWorkerAsync & CancelAsync
  • 简单而好的解决方案。 Tnx ;)
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    此页面可能有用:

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

    【讨论】:

      【解决方案4】:

      这些场景实现起来非常复杂 - 查看用于存储状态的处理程序和布尔变量。

      我建议使用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稍作修改。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-02-29
        • 2020-06-01
        • 1970-01-01
        • 2022-01-25
        • 2014-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多