在表单对象上按住鼠标按钮时的延迟操作(原生 class)

Delayed action while holding the mouse button on a form object (native class)

最近,使用大量示例和提示(我正在学习),我设法为 .Net 表单创建了自己的控件 class。 Full Control Code введите сюда код

如果您试图解释该功能是什么,那么我尝试制作 ProgressBar 的模拟,只是稍作修改。它有多种改变水平的方法。对我来说最有趣的功能之一是能够按住鼠标左键,使级别首先移动到鼠标的指定位置,然后我可以在继续移动鼠标的同时控制它。

如果你尝试简化代码,那么这个过程的管理是这样的:

class Seasonality_ProgressBar : Control

Stopwatch st = new Stopwatch();
MouseButtons mb = MouseButtons.None;

public Seasonality_ProgressBar()
{
}

protected override void OnMouseDown(MouseEventArgs e)
{
   // base.OnMouseDown(e);
    if (!st.IsRunning)
    {
        mb = e.Button;
        st.Start();

        if (e.Button == mb)
        {
            x = e.X;
            y = e.Y;
            timer.Elapsed += OnTimedEvent;
            timer.Start();
        }
    }
    base.OnMouseDown(e);
}


 private void OnTimedEvent(Object source, ElapsedEventArgs e)
 {
     timer.Stop();
     //MessageBox.Show("Сработало");
     float reultation = x - y;
     if (reultation > 0)
     {
         Value = "A";
     }
     else
     {
         Value = "B";
     }
 }

可以看出,过了一段时间方法在timer上启动了 然后,我尝试将此 class 的实例连同我想反映在 ProgressBar 中获得的值的标签一起放置在表单上。我打了这样的电话:

private void seasonality_ProgressBar1_MouseUp(object sender, MouseEventArgs e)
    {
        label2.Text = (-seasonality_ProgressBar1.Value).ToString();
    }

    private void seasonality_ProgressBar1_MouseMove(object sender, MouseEventArgs e)
    {
        label2.Text = (-seasonality_ProgressBar1.Value).ToString();
    }

    private void seasonality_ProgressBar1_MouseDown(object sender, MouseEventArgs e)
    {

        //MessageBox.Show("Привет");

        label2.Text = (-seasonality_ProgressBar1.OnTimedEventValue).ToString();
        int A = 0;
    }

    private void seasonality_ProgressBar1_Click_1(object sender, EventArgs e)
    {
        label2.Text = (-seasonality_ProgressBar1.Value).ToString();
    }

我是绝对获取不到鼠标按住不动,不移动时输出到标签的值。释放时才显示值,但我不喜欢。我也有多个标签渲染(值显然在不断变化)。

请大家帮忙理解,指教。 谢谢

这里最好的方法是创建您的活动。例如

public delegate void OnValueChangedEvent(int value);
public event OnValueChangedEvent OnValueChanged;

每次更改值时都需要触发它属性

public int Value
{
  get => _value;
  set
  {
    if (value >= ValueMinimum && value <= ValueMaximum)
    {
      _value = value;
    }
    Invalidate();
    // Use '?' here to avoid Null reference exception in case your event is not subscribed
    OnValueChanged?.Invoke(_value);
  }
}

那么你需要从主窗体、另一个控件或任何你想要的订阅这个事件。

public Form1()
{
  InitializeComponent();
  seasonality_ProgressBar1.OnValueChanged += SomeEvent;
}

private void SomeEvent(int value)
{
  //Use Invoke here because your event is called from another thread
  Invoke(new Action(() =>
  {
    label2.Text = value.ToString();
  }));
}

此外,请尽量避免使用计时器和您可能编写的任何 'delay' 逻辑,除非它听起来对业务逻辑来说很自然。如果你真的需要它,有一个完美的library 一个事件驱动的开发(喜欢UI staff)