View previous topic :: View next topic |
Author |
Message |
Graham Guest
|
Posted: Wed Oct 26, 2005 12:41 am Post subject: Selection does not stick after resorting |
|
|
I have event handlers which implement programmatic data binding for a VirtualTree. I am using the control as a listview, with AllowMultiSelect = false and SelectionMode = FullRow.
Loading data virtually is working fine, ie. initial load on demand, total load when sort/reverse is required.
The problem is in maintaining the selected row after changing the sort column or reversing the sort direction. The first time there is a reversal or resort, all data items are loaded; the selected row is lost (and the list does not scroll to keep it in view). But subsequently, on selecting a row (using the mouse), a reversal or resort (without reloading the data) keeps the selection and the list scrolls to display it!
I'm wondering whether this behaviour is to do with a timing issue. Perhaps the selection is lost because of the time taken to load data (though only about 1-2 seconds)?
Or is this issue to do with how I'm making the initial selection?
Code: | tree.SelectedRow = tree.TopRow; |
On the other hand, I get the same behaviour when using the mouse to make the initial selection.
Can you help?
Thanks,
Graham |
|
Back to top |
|
|
Infralution
Joined: 28 Feb 2005 Posts: 5027
|
Posted: Wed Oct 26, 2005 1:03 am Post subject: |
|
|
If you run the Database Browser and Dataset Browser samples you'll see they don't have this issue ie you can select the top row then sort by clicking on a column and they behave as you would expect.
I suspect the problem may have to do with the way your objects implement identity equality. When the sort column is changed VirtualTree by default calls UpdateRows(true) which forces the children to be reloaded. If you return a completely new list of children objects in the GetChildren event/method then the current selected item will not match the new objects returned and so Virtual Tree is unable to maintain the selection. There are two possible solutions to this:
1. Implement some form of caching so that you don't create new instances of objects which you have already previously created.
2. Implement the Equals and GetHashCode methods for your class such that two instances that refer to the same underlying data return the same HashCode and Equals returns true. In this way you can create new aliased objects which refer to the same data - but VirtualTree (and other collections) will treat them as being the same object. _________________ Infralution Support |
|
Back to top |
|
|
Graham Guest
|
Posted: Wed Oct 26, 2005 6:51 am Post subject: Selection does not stick after resorting |
|
|
Thanks for the quick reply.
Quote: | If you return a completely new list of children objects in the GetChildren event/method then the current selected item will not match the new objects returned... |
I am not sure if by "new list" you mean a new list instance or a new set of objects in the same list previously assigned to Row.Children. In my case it's the latter.
The "cache" for my VirtualTree is just an ArrayList L, initialised with nulls so the Count property matches the number of potential objects. Initially some of L's items are non-null (depending on the number of displayed rows); they are created and assigned on demand, in a handler for GetRowData.
1. With your first suggestion in mind, I modified the handler for GetChildren so that (after a change to the sort order or direction) instead of clearing L and calling Add in a loop it now just assigns objects to the null items. So I'm no longer creating new instances of objects previously created. Nor am I recreating the collection L.
2. As to your second suggestion, I implemented Equals and GetHashCode but found that neither is invoked when reversing the sort direction. Only Equals gets invoked when changing the sort order.
The selected row is not maintained using either 1 or 2 or both of the above changes. I'm still missing something!
I'm using version 2.2.0 of Virtual Tree.
Thanks in advance,
Graham |
|
Back to top |
|
|
Infralution
Joined: 28 Feb 2005 Posts: 5027
|
Posted: Wed Oct 26, 2005 12:35 pm Post subject: Re: Selection does not stick after resorting |
|
|
Graham wrote: | I am not sure if by "new list" you mean a new list instance or a new set of objects in the same list previously assigned to Row.Children. In my case it's the latter. |
What is important is if the objects in the list are the same objects as were previously displayed (not the list itself).
Quote: | The "cache" for my VirtualTree is just an ArrayList L, initialised with nulls so the Count property matches the number of potential objects. Initially some of L's items are non-null (depending on the number of displayed rows); they are created and assigned on demand, in a handler for GetRowData. |
OK I think I see the issue (although it is a little difficult without code). From your description you are setting the DataSource as a list of nulls and then when GetRowData is called you are retrieving the object at the given Row index and returning the properties.
The problem with this approach to loading on demand is that VirtualTree expects that the objects returned by the child list Item property are the actual objects - not a placeholder null. Virtual Tree uses the item associated with a row to determine its identity and maintain the selection. In your case all the items will be null initially so Virtual Tree can't check for equality.
If you want to implement on demand loading of objects then the way to do it is to implement your own collection that implements thestandard IList interface. You can use an array list or hashtable underneath to maintain the cached (already loaded) items. This is actually fairly easy - we can help if you have any issues. There is also quite a bit of documentation on MSDN about this.
If I have totally missed the point of what you are doing then you may need to email us a sample project (to support@infralution.com) so that we can better understand your issue. _________________ Infralution Support |
|
Back to top |
|
|
|