Well, in case anyone else comes along, I thought I'd post my solution. It basically caches all the expanded nodes and the selected node, resets the dataprovider, then restores those states. There's a little flickering, but it's minimal. I wrote the functions recursively, but if you run into that being a problem you could just rewrite it.
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="creationComplete()"> <mx:Script> <![CDATA[ import mx.events.ListEvent; import mx.collections.SortField; import mx.collections.Sort; import mx.collections.ArrayCollection; [Bindable] private var treedata:ArrayCollection = new ArrayCollection([]); private function creationComplete():void { var sort:Sort = new Sort; sort.fields = [new SortField("label", true)]; treedata.sort = sort; for (var i:int = 0; i < 4; i++) { var node:Object = {label:"parent"+i, children:new ArrayCollection([])}; for (var c:int = 0; c < 3; c++) { var child:Object = {label:"child"+c}; node.children.addItem(child); } node.children.sort = sort; node.children.refresh(); treedata.addItem(node); } treedata.refresh(); } private function renameBtnClick():void { tree.editable = true; var e:ListEvent = new ListEvent(ListEvent.ITEM_EDIT_BEGINNING, false, false, 0, tree.selectedIndex); tree.dispatchEvent(e); } private var editedItem:Object; private var expandedNodes:Array = []; private function renameEnd(e:ListEvent):void { tree.editable = false; editedItem = e.itemRenderer.data; callLater(resetTreedata); } private function resetTreedata():void { expandedNodes = []; getExpandedNodes(treedata); var nodeParentList:ArrayCollection = findParentList(editedItem, treedata); nodeParentList.refresh(); tree.dataProvider = treedata; callLater(expandAndSelect); } private function expandAndSelect():void { expandNodes(treedata); tree.selectedItem = editedItem; } private function findParentList(node:Object, list:ArrayCollection):ArrayCollection { var index:int = list.getItemIndex(node); for each (var o:Object in list) { if (o == node) return list; if (o.children && o.children.length) { var result:ArrayCollection = findParentList(node, o.children); if (result) return result; } } return null; } private function getExpandedNodes(list:ArrayCollection):void { for each (var o:Object in list) if (tree.isItemOpen(o)) { expandedNodes.push(o); if (o.children && o.children.length) getExpandedNodes(o.children); } } private function expandNodes(list:ArrayCollection):void { for each (var o:Object in list) if (expandedNodes.indexOf(o) != -1) { tree.expandItem(o, true); if (o.children && o.children.length) expandNodes(o.children); } } ]]> </mx:Script> <mx:Tree id="tree" dataProvider="{treedata}" width="200" height="400" editable="false" itemEditEnd="renameEnd(event)" /> <mx:Button label="Rename" click="renameBtnClick()"/> </mx:Application> On Nov 28, 2007 1:19 PM, Pan Troglodytes <[EMAIL PROTECTED]> wrote: > Well, that's really unfortunate, as I'm trying to deliver an application > based on Flex 2 that has this behavior. I'm going to try hacking something > together to save/restore the tree layout after resetting the dataprovider. > If anyone else has any suggestions, I'd really appreciate them. > > > On Nov 28, 2007 11:38 AM, Alex Harui <[EMAIL PROTECTED]> wrote: > > > Tree doesn't really support sorting. We hope to provide an example > > in 3.0 of how to get Tree to handle sorting > > > > ------------------------------ > > *From:* [email protected] [mailto:[EMAIL PROTECTED] *On > > Behalf Of *Pan Troglodytes > > *Sent:* Wednesday, November 28, 2007 8:27 AM > > *To:* flexcoders > > *Subject:* [flexcoders] a tree that keeps sorted > > > > I'm trying to build a tree (Flex 2) that keeps its nodes sorted, even > > when you edit them. I keep running into problems, though. Here's the basic > > app, without the auto-sorting: > > > > <?xml version="1.0" encoding="utf-8"?> > > <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" > > layout="vertical" creationComplete="creationComplete()"> > > <mx:Script> > > <![CDATA[ > > import mx.collections.SortField; > > import mx.collections.Sort; > > import mx.collections.ArrayCollection ; > > > > [Bindable] private var treedata:ArrayCollection = > > new ArrayCollection([ > > {label:"node0"}, > > {label:"node1"}, > > {label:"node2"}, > > {label:"node3"}, > > {label:"node4"} > > ]); > > > > private function creationComplete():void > > { > > var sort:Sort = new Sort; > > sort.fields = [new SortField("label", true)]; > > treedata.sort = sort; > > } > > ]]> > > </mx:Script> > > <mx:Tree > > id="tree" > > dataProvider="{treedata}" > > width="200" > > editable="true" > > /> > > </mx:Application> > > > > > > Okay, so that lets you click on the nodes and edit them. What should be > > done to get the nodes to re-sort after editing? I've tried: > > > > itemEditEnd="treedata.refresh()" > > > > Doesn't work, because when itemEditEnd has been called, the dataprovider > > hasn't actually been updated. > > > > itemEditEnd="callLater(treedata.refresh, [])" > > > > Sorta works, until renamed "node2" to "node" and then it just > > disappears. If you rename the last node to something that would make it the > > first node, you get an error. > > > > private function reload():void > > { > > treedata.refresh(); > > tree.dataProvider = treedata; > > } > > > > itemEditEnd="callLater(reload)" > > > > This works ok, until you have a node with children like: > > {label:"node0", children:new ArrayCollection([{label:"child-0-1"}, > > {label:"child-0-2"}])}, > > And you expand it before renaming "node4" to "node". Then you get an > > error. > > > > I've also tried this without using itemEditEnd and instead having the > > node be a custom object that throws events. I run into the same issues. > > What's the "right" way to do something that should be a pretty simple task? > > > > -- > > Jason > > > > > > > > -- > Jason -- Jason

