简体   繁体   中英

WPF Treeview stackoverflow if SelectionChanged event fires too quickly?

I have a TreeView with 1000 items. When I select an item, the TreeView fires an event so I can update something in my GUI. The event handler is non recursive and has no loops, but it does take a little bit of time to complete, maybe 100ms.

If I select the top item and use the down arrow to scroll through items slowly, everything works fine, but if I hold down the arrow key, the event fires too quickly and I get a stackoverflow exception.

I thought about putting a timer in the TreeView so the SelectionChanged event can only fire every 100ms or so, but that seems very hackish. Any ideas for fixing this?

I've seen stuff like this happen on winforms as well. One way that I have seen people implement is to have a delayed event handler. Such that it fires only after the said item has been selected for a specified time period.

So the way that works is you have an event handler that executes a timer. The timer gets reset whenever the selectionchanged event is fired. Your timer would be maybe 500ms so if the selected value is still selected after 500ms it will then fire your actual event code you need handled.

Not saying this is the best way just a way I have seen it handled in windows forms.

Run the event handler asynchronously. The simplest way of doing this is as follows:

void SelectionEventHandler(object sender, EventArgs e)
{
    var ownerElement = sender as FrameworkElement; // this should be the TreeView itself
    ThreadPool.QueueUserWorkItem(o => {

        // Do stuff 

        ownerElement.Dispatcher.BeginInvoke(new Action(() => {

            // Update UI in response to stuff being done

        });
    });
}

If you use something like The Reactive Framework then you can cut down the cruft involved with ThreadPools, etc quite considerably.

You might also consider the Parallel Task library with it's Task<T> class - You can get a .NET 3.5 version by downloading the reactive framework.

NOTE: Running the handler asynchronously should stop the Stack Overflow, however it won't stop the handler from running 1000 times when the user rolls down the list. If you want to do that you can either implement a delay timer, or if you're using the Reactive framework, it has some features which can do this kind of thing for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM