按住鼠标在窗体对象上的操作延迟(本地类) [英] Delayed action while holding the mouse button on a form object (native class)

查看:89
本文介绍了按住鼠标在窗体对象上的操作延迟(本地类)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,通过使用许多示例和技巧(我正在学习),我设法为.Net表单创建了自己的控件类.

可以看到,一段时间后该方法在计时器上开始运行 然后,我尝试将此类的一个实例以及希望反映在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;
 

并且您每次更改Value属性时都需要将其触发

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

此外,请尝试避免使用计时器和您可能组成的任何延迟"逻辑,除非对于业务逻辑而言听起来很自然.如果您确实需要它,那么可以使用完美的进行事件驱动的开发(如UI工作人员)

>

Recently, using a lot of examples and tips (I'm learning), I managed to create my own control class for the form .Net. Full Control Code введите сюда код

If you try to explain what the feature is, then I tried to make an analogue of ProgressBar, only slightly modified. It has various methods of changing the level. One of the most interesting ones for me was the ability to press and hold the left mouse button so that the level first shifted to the specified location of the mouse, and then I was able to control it while continuing to move the mouse.

If you try to simplify the code, then the management of this process looks like this:

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";
     }
 }

It can be seen that after a while the method starts on the timerю Then I tried to place an instance of this class on the form along with the label on which I wanted to reflect the value obtained at the ProgressBar. I made such calls:

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

I absolutely can’t get the value output to the label when the mouse is pressed and held, without movement. The value is displayed only when released, but I don’t feel like it. I also have multiple rendering of the label (the value is apparently constantly changing).

Please help to understand, teach. Thank.

解决方案

The best way here is to create your event. For example

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

And you need to fire it every time you change the Value property

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

Then you need to subscribe to this event from the main form, another control or whatever you want.

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

Also, try to avoid using timers and any 'delay' logic you may make up unless it sounds natural for the business logic. If you really need it, there is a perfect library for an event-driven development (like UI staff)

这篇关于按住鼠标在窗体对象上的操作延迟(本地类)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆