Mr_LinDowsMac
Mr_LinDowsMac

Reputation: 2702

Trigger action after delay

I have the following code in an OnTextChanged event in a Xamarin.Forms project:

async void OnTextChanged(object sender, TextChangedEventArgs e)
        {

            if (this.txtClientFilter.Text.Length > 4)
            {
                var client_list= App.ClientManager.GetTasksAsync(txtClientFilter.Text);
                var template = new DataTemplate(typeof(TextCell));

                template.SetBinding(TextCell.DetailProperty, "nom_ct");
                template.SetBinding(TextCell.TextProperty, "cod_ct");

                listview.ItemTemplate = template;
                listview.ItemsSource = await client_list;

            }
        }

As you can see, almost every keypress is trying to make a request (via a GetTaskAsync method). I don't want to fire every keypress, I would like to ignore some keypress under 1000 milliseconds.

How can I do that? I found some examples using Task.Delay() but didn't work as expected.

Upvotes: 0

Views: 352

Answers (2)

nix
nix

Reputation: 2285

Create a _lastClickTime private property of type DateTime on your page and add this to the beginning of your button click handler:

if (DateTime.Now - _lastClickTime < new TimeSpan(0, 0, 0, 0, 1000))
{
    return;
}
_lastClickTime = DateTime.Now;

Have I misunderstood your question?

Upvotes: 0

serhiyb
serhiyb

Reputation: 4833

    private int taskId = 0;

    private async void ExecAutoComplete()
    {
        var client_list = App.ClientManager.GetTasksAsync(txtClientFilter.Text);
        var template = new DataTemplate(typeof(TextCell));

        template.SetBinding(TextCell.DetailProperty, "nom_ct");
        template.SetBinding(TextCell.TextProperty, "cod_ct");

        listview.ItemTemplate = template;
        listview.ItemsSource = await client_list;
    }

    private void TryExecute(int taskId)
    {
        if (this.taskId == taskId)
            this.Invoke((MethodInvoker)(ExecAutoComplete));
    }

    private async void OnTextChanged(object sender, TextChangedEventArgs e)
    {
        ++taskId;
        Task.Delay(1000).ContinueWith(t =>  TryExecute(taskId));
    }

We create unique taskId on each textChange and if after 1000ms taskId remains the same (no more text changes) we execute actual call.

Upvotes: 3

Related Questions