Wednesday, June 14, 2006

Updated SFTreeView

I wrote a two-part article in the July and August issues of FoxTalk called "The Mother of all TreeViews" that presented a class library providing all the features you (or at least I) would ever need in a TreeView, including automatically dealing with the twips coordinate system used by the control, handling drag and drop, only loading parent nodes at startup, saving and restoring expanded and selected nodes, and so forth.

Andrew Nickless emailed me today about a bug: navigating the TreeView using the up and down arrows didn't cause the sample form that accompanied the article to refresh and show the properties for the selected node. Fortunately, it was easy to fix:

1. In TreeNodeClick, change the IF statement as shown:

*** if isnull(.oTree.SelectedItem) or toNode.Key <> .oTree.SelectedItem.Key
if isnull(.oTree.SelectedItem) or not toNode.Key == .cCurrentNodeKey

2. Add a new cCurrentNodeKey property

3. Add this line to SelectNode right after the assignment to cCurrentNodeID:

.cCurrentNodeKey  = loNode.Key

However, while I was looking into this, I decided to delve into another weird behavior that had bugged me for a while: sometimes clicking on the + to expand a parent node showed the placeholder "Loading..." node rather the actual children. The reason is that the Expand method of the TreeView didn't fire, and that method was responsible for removing the placeholder node and adding the child nodes. The weird thing is that it wasn't consistent; I could only make it happen about 25% of the time, if that. And given that I haven't seen that happen in other applications using a TreeView, it was clearly something I'd done in my class.

Long story short, it turned out (by trial and error, sadly) that code I had in the MouseMove method seemed to be the culprit. I say "seemed" because after removing it, I couldn't reproduce the behavior, but given that it didn't always happen, and of course it never happened when tracing the code, it's darned hard to confirm that it's gone for good. MouseMove called TreeMouseMove (thanks to Steve Black for drilling "events call methods" into my brain), which didn't do anything; I put it there in case I wanted to handle that in a subclass. Turns out I never have, so removing that behavior was no big deal.


Anonymous said...

Thanks for following up on that, Doug. Folks can get those code examples by subscribing, right?

Doug Hennig said...

Yes, that's correct, Michael.

Anonymous said...

I had removed the IF from the TreeNodeClick which meant it was doing some extra work occasionally, works great now thanks. The PropertiesContainer has the visibility set in the refresh, but then goes on to refresh each control in that container. Apart from testing the visibility in each control is there any way of stopping it doing this?

Doug Hennig said...

The container isn't refreshing its controls; that's the native behavior of refreshing the form. I normally test for This.Visible in the Refresh method of contained controls if necessary.

Anonymous said...

Doug, I am an online subscriber to Foxtalk2 but cant find how to download the classes, are they still available?

Doug Hennig said...

I can't find it anymore, either. I'm planning on posting every article I've written on the Technical Papers page of at some point when I get a chance.