1

I have an event (ctc) that fires when a text change occurs in a ComboBox, I want to delay its firing for one second. I wrote this code so far and put it in the MainWindow :

Timer aTimer = new Timer();
    aTimer.Interval = 1000;
    aTimer.Elapsed += new ElapsedEventHandler(ctc);
    aTimer.Enabled = true;

I am new to WPF and I want to know what to put in ElapsedEventHandlerparenthesis, I put the even name but I am getting an error. Also do I need to add anything to Xaml code for the ComboBox ?

Little Programmer
  • 181
  • 1
  • 5
  • 15
  • 3
    if you are using binding and .net 4.5+, then you can also use `Delay` property (https://msdn.microsoft.com/en-us/library/system.windows.data.bindingbase.delay(v=vs.110).aspx) – ASh Jul 19 '16 at 08:26
  • 1
    Why do you want to delay the event? what are you trying to achieve? could you give us some more information? maybe there's a better solution all together – MichaelThePotato Jul 19 '16 at 08:40
  • _"when a text change occurs in a ComboBox"_ - do you mean "when selected item changed"? – Sam Jul 19 '16 at 09:07
  • no when text change occurs, I created an event for that. when the user starts typing this event occurs and starts looking for a match on a database (sql server) – Little Programmer Jul 19 '16 at 09:09
  • @LittleProgrammer are you talking about a textbox or a combobox? You mightve confused something. – Mafii Jul 19 '16 at 09:37
  • I am sure combobox – Little Programmer Jul 19 '16 at 09:38
  • 1
    I believe OP means `IsEditable="True"`, see my answer. – Sam Jul 19 '16 at 09:42

2 Answers2

8

Well, the simplest way is to use Delay property as @ASh mentioned. I did not know about it before, but I tried and it is amazing:

XAML:

 <ComboBox IsEditable="True" Text="{Binding ComboBoxText, Mode=OneWayToSource, Delay=1000}">
    <ComboBoxItem Content="item1" />
    <ComboBoxItem Content="item2" />
    <ComboBoxItem Content="item3" />
</ComboBox>

View-model:

private string comboBoxText;

public string ComboBoxText
{
    get { return this.comboBoxText; }
    set
    {
        if (this.SetProperty(ref this.comboBoxText, value))
        {
            Trace.WriteLine("*** New text: " + value);
            // RunDatabaseSearch(value);
        }
    }
}

Where SetProperty is implementation of INotifyPropertyChanged.

Watch Output window in Visual Studio, text will appear after a second of user's last typing.

Sam
  • 1,384
  • 2
  • 20
  • 30
-1

This should be better:

After .Net 4.0 you can use (thank you ASh):

await Task.Delay(1000); 

Its a non blocking call.

Then, after this statement, just change your text.

If you happen to be using .Net 4:

Here is a sample implementation of Delay in .Net 4.0

There is also Thread.Sleep, but it seems to be bad practice because it costs many resources (thanks Eli Arbel, Sam):

await System.Threading.Tasks.Task.Run(() => System.Threading.Thread.Sleep(1000));

without full qualifiers:

await Task.Run(() => Thread.Sleep(1000));
Community
  • 1
  • 1
Mafii
  • 7,227
  • 1
  • 35
  • 55
  • Stupid question, but where do I put it in the mainwindow or inside the even I want to delay its execution ? – Little Programmer Jul 19 '16 at 08:24
  • If you always want to delay the change, put it before you set the value to your Binding property, inside the binding property set accessor. You could also just delay the OnPropertyChanged. Do you use mvvm or just plain code-behind? – Mafii Jul 19 '16 at 08:28
  • @EliArbel why is that? Could you elaborate? – Mafii Jul 19 '16 at 08:34
  • 1
    @Mafii `Thread.Sleep` will hold thread (created by `Task.Run` in thread pool) in full amount of time, while `Task.Delay` will allow to reuse this thread by thread pool until delay expired. – Sam Jul 19 '16 at 08:45
  • I am using a plain code-behind I suppose, the thing is I want to delay the event firing not fire it then wait a second then execute it. – Little Programmer Jul 19 '16 at 08:47
  • @Sam check my edit - is this better? I assume the implementation example is about what the newer .net implements, yes? – Mafii Jul 19 '16 at 08:51
  • @Mafii Yes, it is better, and as prove there also provided section "_How NOT to implement Task.Delay 4.0_", where `Thread.Sleep` placed inside task. – Sam Jul 19 '16 at 08:59