Hi, I'm currently evaluating your product and one of the things I need it to do is display realtime information while allowing the user to group and sort. I'm currently using the UltraDataSource to manually update the cells as changes occur to the data (any better ideas?). Currently however, when I group by a field that changes, the items within those groups don't change groups. The same is for sorting, the sort order doesn't change (as expected). I realize that requiring the control to regroup and resort is expensive and probably something that it doesn't do without being told to. I've researched the methods and properties on the grid and have explored the forums for an answer without any luck. Any ideas?
-mt
You should be able to use the RefreshSort method off of the SortedColumns collection of a band in order to refresh the grouping/sorting.
-Matt
Yeah, I just realized how to change the default search date range on the forums so I was able to find this:
http://forums.infragistics.com/forums/p/6699/28304.aspx#28304
Which indicates the same solution you've proposed. I need the group states to remain the same, and I see in the above post that you refresh the sort position of an individual row.
My problem now is how can I obtain the UltraGridRow instance that corresponds to the row I'm updating when I call:
ultraDataSource.Rows[index].SetCellValue(key, newValue, true);
There's no way to get the corresponding UltraGridRow from the UltraDataRow without looping through the Rows collection. What you might be able to do is set a flag before the SetCellValue call and listen for the AfterRowUpdate, which will give you the row that was updated. You would then reset the flag after the SetCellValue method completes.
I thought of that as well, but it doesn't look like the AfterRowUpdate event is fired when I call SetCellValue. I figured it would only fire when the row update comes from the user, instead of from the data source.
I did enumerate over the group rows and saved the state before the cell update, then restored the state after the cell update, but this felt like a hack and even so, still behaves strangely as the scroll position, selected row, etc. are being reset as well.
Any other ideas? Maybe I shouldn't be using the UltraDataSource to update my values. Would operating in a pure unbound mode help any?
There is no such thing as a pure unbound mode with the WinGrid. Is there a particular reason that you can't simply update the row in the grid directly instead of the underlying UltraDataRow? This would be the ideal way since then you're being consistent with updating the grid from one place instead of two.
I had the same problem today when i was first using the UltraGrid.
I think the main problem is:- If you add a new row to the DataSource with Rows.Add(), all Cells are empty (null) but the row is "bubbled up" to the grid immediately... and of course it is not positioned where you like it to be- Then you add the Cell-Values via newRow["CellName"] = "abc" or something like that. But now the Grid does not update the sorting or grouping - which is understandable in terms of performance and annoyance.
You have work-around the problem by getting the corresponding GridRow (via the index of the new added row) and refreshing the sort. This works, but still every new row is sorted twice by grid: First when you add it and second time when you force it so.
An other way would be to suspend the binding between the DataSource and the Grid like so:
data1.SuspendBindingNotifications();UltraDataRow row = data1.Rows.Add();row["Field1"] = AName;row["Field2"] = AName;...data1.ResumeBindingNotifications();
You should put a try-finally around that so that the binding is resumed in every case (in case it would crash somewhere in between)
Now a new row is only sorted once when it bubbles up to the grid. And this way you are able to add a lot of new rows very quickly and then let the grid refresh once - instead of on time for every new row.
This works for me - hope it helps others too
I've figured out some things that others out there that are following this post might be interested in. I noticed a large number of "Not supported exceptions" being thrown in my program trace after making the above changes, however these exceptions were not bubbling up to my application. Even though things were working, I didn't like exceptions being thrown left and right.
I then thought about what was happening and wondered what happens when I update the grid directly while my underlying datasource is readonly. For my situation, my datasource is readonly since it's a realtime display of things going on in the system. I used reflector and followed what happens as cell values are set and as expected, they are updating the value of the underlying cell's property descriptor, which in my case was a UltraDataColumnPropertyDescriptor (since I'm using UltraDataSource). Since I've set this datasource to be readonly, the code in reflector told me that UltraDataColumnPropertyDescriptor was throwing an InvalidOperationException. I commented out the line of code that sets the cells value directly and the exceptions went away. I now update the UltraDataSource values only.
So if others out there are reading this, be careful with this approach. You may be better off setting the datasource values and letting those values bubble up to the grid. In my case, all I really needed to do was reset the sort position of the row and since I new the index of the row being updated, I was able to still do that, even though I'm updating the value through the datasource.
Thanks for you help Matt!
You would update a specific cell by indexing into the row's Cells collection and setting the value, such as row.Cells["SomeKey"].Value = ...
The other methods look to be in order.
Okay, how can I update the row directly? I see the the Rows collection of the grid and using Rows.GetRowWithListIndex seems to do the trick (since I have the index of the item in the underlying datasource). Also, calling RefreshSortPosition() puts the row into the correct group and behaves as expected. Great!
So am I doing that right?