Hi,
I have an UltraGrid that is bound to a datasource that changes in realtime. By realtime i mean that rows can be added or removed to the datasource. Supposing I have rows A,B,C,D,E,F,G,H,I. I select rows C,D with D being the active. If row I gets deleted, the selected row shifts to E and on subsequent deletes to the datasource, the selection keeps shifting down to F, G, H etc.
To re-iterate my datasource is changing from the backend, the user is not deleting.
What could this reselection be due to?
Infragistics version: 10.3
Any help would be really appreciated.
What's the DataSource? It sounds like your data source is doing something it shouldn't be doing. Is it a DataSet, a DataTable, an UltraDataSource, a BindingList, some custom object?
It's a DataTable. I think it happens when one row gets deleted, I can see the grid.Selected.Row having another row in the collection that I have not selected. Is there a way to disable this so that selection only happens on user click and not programmatically? Or is there any other reason the grid's selection is including new rows?
The BeforeSelect/AfterSelect are not called at all- they seem to be only fired during user selection.
The issue here is that the code somewhere internally changes the grid.selectedRows.
The event RowsCollection.Remove() of the DataView is causing the ListChange event to fire with ListChangeType.Reset. At this point i notice my grid.Selected.Rows collection picks up something else.
It sounds to me like your DataSource is doing things it should not be doing. If your data source sends a reset notification, then the grid will lost everything. It has to. That's what reset means. The grid has to throw away ALL of the data and essentially create an entire set of new rows based on the new data. It will lose selection, sorting, filter, etc.
But a remove shouldn't automatically cause a reset. If that's happening, then something else in your code is triggering the Reset, or else your data source is doing something wrong.
Does the grid decide to retain selected rows based on index?
No. Index has nothing to do with it.
When the grid binds to a data source, the DataSource provides a list of objects to represent the rows. The UltraGrid creates an UltraGridRow object for each of these objects, and the UltraGridRow keeps a reference to that object (which is called the ListObject). That's how grid rows link up to data source rows (ListObjects). If your data source sends a Reset notification, that means that every ListObject the WinGrid has is no longer valid - or at least that it may not longer be valid. But the effect is the same. The grid has to assume that all ListObjects are invalid and so the grid throws them all out and starts from scratch creating an entirely new set of UltraGridRows based on the new ListObjects from the data source. In this case, all selected rows are cleared. So it sounds like something else in your code is re-selecting some of the rows, maybe.Reset is very destructive. It tells the bound controls to throw away everything and start over. So the data source should not be sending a Reset notification when removing a row. It should only be sending a notification with ListChangedType.ItemDeleted.
we do a row.Table.Rows.remove(). Would that be causing the reset?
As far as I'm aware, no.
If you think about it, that would not make a lot of sense. There's a ListChangedType value for ItemRemoved. So why would removing a single item fire a Reset notification instead of just ItemRemoved? That would make ItemRemoved pointless. Is your data in a hierarchy or just a flat list? There might be some cases where both ItemRemoved and Reset fire, but in such a case, the Reset would fire on a child band, not the same band - like if you removed a parent row that has child rows, that might trigger a reset on the child band. That would make some kind of sense. But I'm not even sure about that and it certainly shouldn't trigger a Reset for just a flat list of data. If you are tired of fighting with this, you might want to consider just working around it. You would have to store some kind of key values from each selected grid row before the Remove. The loop through the grid rows and find the matching rows and re-select them after the Remove completes. You can't use the row indices, since they won't be the same before and after.