C#中KeyUp事件处理程序的速率限制

时间:2013-05-12 12:26:14

标签: c#

我想在用户输入时验证文本字段的输入。这个功能工作正常,但是我想限制验证,因为它正在点击外部API。我想仅在用户未输入750毫秒后才执行验证。

ATM我只是使用它:

private void Configure_Load(object sender, EventArgs e)
{
    endpointBox.KeyUp += EndpointBox_KeyUp;
}

void EndpointBox_KeyUp(object sender, KeyEventArgs e)
{
    TestHTTP200(endpointBox.Text);
}

3 个答案:

答案 0 :(得分:1)

您需要一个等于JavaScript的SetTimeout方法的方法。当用户提供更多输入时,可以取消此操作:

代码取自here

    public static IDisposable SetTimeout(Action method, int delayInMilliseconds)
    {
        System.Timers.Timer timer = new System.Timers.Timer(delayInMilliseconds);
        timer.Elapsed += (source, e) =>
        {
            method();
        };

        timer.AutoReset = false;
        timer.Enabled = true;
        timer.Start();

        // Returns a stop handle which can be used for stopping
        // the timer, if required
        return timer as IDisposable;
    }

然后,您可以在密钥处理程序中使用它:

    void EndpointBox_KeyUp(object sender, KeyEventArgs e) 
    {
         IDisposable timeout = SetTimeout(() => TestHTTP200(endpointBox.Text), 750);
         if (this.currentTimeout != null) {
             this.currentTimeout.Dispose();
             this.currentTimeout = timeout;
         }
    }

至少这是基本原则,每次用户输入你重新启动750毫秒超时来做你的事情,并取消任何待定的计时器。

更新:完整的代码示例:

public partial class Form1 : Form
{
    private IDisposable currentTimeout;

    public Form1()
    {
        InitializeComponent();
    }

    private void EndpointBox_KeyUp(object sender, KeyEventArgs e)
    {
        IDisposable timeout = TimerHelper.SetTimeout(() => TestHTTP200(EndpointBox.Text), 750);
        if (this.currentTimeout != null)
        {
            this.currentTimeout.Dispose();
            this.currentTimeout = timeout;
        }
    }

    private void TestHTTP200(string text)
    {
        //...
    }
}

public class TimerHelper
{
    public static IDisposable SetTimeout(Action method, int delayInMilliseconds)
    {
        System.Timers.Timer timer = new System.Timers.Timer(delayInMilliseconds);
        timer.Elapsed += (source, e) =>
        {
            method();
        };

        timer.AutoReset = false;
        timer.Enabled = true;
        timer.Start();

        // Returns a stop handle which can be used for stopping
        // the timer, if required
        return timer as IDisposable;
    }
}

答案 1 :(得分:1)

使用Timer控件

System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
private void Configure_Load(object sender, EventArgs e)
{
    endpointBox.KeyUp += EndpointBox_KeyUp;
    myTimer.Tick +=new EventHandler(OnTimedEvent);       //EDIT: should not be `ElapsedEventHandler`  
    myTimer.Interval=750;   
}

void EndpointBox_KeyUp(object sender, KeyEventArgs e)
{    
    myTimer.Stop();
    myTimer.Start();   
}


 private void OnTimedEvent(Object myObject,EventArgs myEventArgs) 
{
      myTimer.Stop();
      TestHTTP200(endpointBox.Text);
}

答案 2 :(得分:0)

wrap_content

这就是你如何使用这个课程using System; namespace Azine_Library.Misc { /// <summary> /// Represents a way to delay something, eg. something an event handler does, update-ion of a control, object or to run a method, This class '<see cref="DelayUpdate"/>' /// is intended to be used as a delayer of some sort and contains an event, '<see cref="PushUpdate"/>' that would be subcribed to an event handler where then the code /// intended to be delayed would go. This object also contains a method, '<see cref="delay"/>' that when called delays the code written/located within the event handler /// that is handling the '<see cref="PushUpdate"/>' event. The method, <see cref="delay"/> should be called from an event handler or a method of some sort that would orginally /// execute the code written/located within the event handler described above also. An example of how this object can interact with another object is described and documented in great detail /// within the documentation for "Azine_Library", also an example program is available with the documentation. /// </summary> public class DelayUpdate { // Written, 17.06.2017 #region Fields / Properties /// <summary> /// Occurs when the provided time (interval:) has elapsed /// </summary> public event EventHandler PushUpdate; /// <summary> /// READONLY. the amount of times the timer has ticked since the last call to delay, (DelayUpdate.delay). /// </summary> public int updateCounter { get; private set; } /// <summary> /// The amount of time [this] waits for until it pushes the update. (Milliseconds). default value: '500'. /// </summary> public int interval { get; set; } /// <summary> /// Holds the amount of times [this] raises the "DelayUpate.PushUpdate" event every call to DelayUpdate.delay() method. default value: '1'. /// </summary> public int updatesPerPush { get; set; } private System.Diagnostics.Stopwatch stopWatch; private System.Windows.Forms.Timer timer; #endregion #region Constructors /// <summary> /// Initializes a new instance of type, 'DelayUpdate'; sets the classes' properties to the defaults. /// </summary> public DelayUpdate() { //Initializing Variables this.updateCounter = 0; this.interval = 500; this.updatesPerPush = 1; this.stopWatch = new System.Diagnostics.Stopwatch(); this.timer = new System.Windows.Forms.Timer(); //Sub-ing Events this.timer.Tick += this.Timer_Tick; } #endregion #region Methods /// <summary> /// Delays the raising of the event, PushUpdate; call this method when a property of an object has changed. eg, TextBox.TextChanged => DelayUpdate.delay(); /// </summary> public void delay() { // Written, 13.06.2017 this.timer.Start(); this.stopWatch.Restart(); this.updateCounter = 0; } #endregion #region Events /// <summary> /// Raises the 'DelayUpdate.PushUpdate' event. /// </summary> private void onPushUpdate() { //Written, 26.05.2017 : 5:22pm if (PushUpdate != null) PushUpdate.Invoke(this, new EventArgs()); } #endregion #region Event Handlers private void Timer_Tick(object sender, EventArgs e) { // Written, 13.06.2017 if (this.stopWatch.ElapsedMilliseconds > this.interval) { if (this.updateCounter < this.updatesPerPush) { this.timer.Stop(); this.onPushUpdate(); } this.updateCounter++; } } #endregion } }

假设您有一个WinForm,它在目录中搜索有文本框的文件,&#34; search_textBox&#34;并附加了一个textChanged事件处理程序:

DelayUpdate.cs

您可以引用该类namespace DelayUpdateExample { public partial class Form1 : Form { public Form1() { InitializeComponent(); this.search_textBox.TextChanged += this.Search_textBox_TextChanged; } private void Search_textBox_TextChanged(object sender, EventArgs e) { } } } 并初始化它。如此订阅DelayUpdate.cs事件:

DelayUpdate.PushUpdate

在textChanged事件处理程序中,您可以像这样调用private DelayUpdate delayUpdate; public Form1() { InitializeComponent(); this.delayUpdate = new DelayUpdate() { interval = 500, updatesPerPush = 1, }; this.delayUpdate.PushUpdate += this.DelayUpdate_PushUpdate; this.search_textBox.TextChanged += this.Search_textBox_TextChanged; } private void DelayUpdate_PushUpdate(object sender, EventArgs e) { throw new NotImplementedException(); } ..

DelayUpdate.delay()

然后,您想要延迟的代码会进入您订阅的private void Search_textBox_TextChanged(object sender, EventArgs e) { this.delayUpdate.delay(); } 。像这样:

DelayUpdate_PushUpdate(object, EventArgs)