views:

37

answers:

1

Hi All,

I am using the input from a TextBox to filter information displayed in a ListBox. I want the filtering to occur each time a key is pressed.

The problem I am faced with is that if the user types a second, third etc. character, the filter will carry on through for each of the key presses. E.g. The user types 'a' and the filtering starts, before filtering for the letter 'a' is finished, the user adds the letter 'b' so the complete search string is now 'ab'.

At this point, what I want to happen is for the first filter to stop completely and start the new filter on 'ab' from scratch.

private bool Interrupt = false;
private bool Searching = true;

private void tbxFilter_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (Searching)
    {
        Interrupt = true;
    }
}

private void tbxFilter_KeyUp(object sender, KeyEventArgs e)
{
    Searching = true;

    foreach (MyObject o in ListOfMyObjects)
    {
        if (Interrupt)
        {
            Interrupt = false;
            break;
        }
        else
        {
            DoFilter(o);
        }
    }

    Searching = false;
}

The code above shows roughly what I have at the moment with some application specific pieces removed (like Types and object names).

What i would like ideally to do is be able to pause at the beginning of the second key press (until Searching has been set to false - indicating that all other searches have exited), but adding a while loop to check for that will just lock the program at that point.

Is there a way to a way to accomplish this?

Thanks

EDIT: The control that is displaying the items is a ListBox / ListView control.

A: 

I would create a worker thread for the filtering. When a new filter process is initiated the running worker thread is canceled (by a setting a flag or cancel token, see .net 4.0 Task class).

When the thread is finished, you take the result and display it in one action on the GUI thread.

testalino
Using a single action to update the interface is actually the cause for me implementing the search in this way. I was initially using an ICollectionView which has a Filter delegate to provide built in filtering, the filtering itself is quite fast (still not as quick as i would like, but maybe acceptable) however, when the changes are then rendered at the end of the process, there is a several second lag during which the UI is completely unresponsive as all of the chnages are being made in the UI thread.
Andy
In Windows.Forms you can use pinvoke to disable updating while settings the data. This will give you a major speedup. If you are using WPF, there are similar ways (not pinvoke, but there are optimizations) to set data in one call.
testalino