Hello,
I'm trying to create a simple real-time application with the grid control.
Currently our data source is an observable collection of objects that implement INotifyPropertyChanged. It consists of a grid of 1000 rows and 20 columns, where every single value in the data source is updated every 500ms. This means that there are 40,000 updates every second to the data source.
xamDataGrid will lazy subscribe to each row as it appears on screen, however it never unsubscribes, meaning that once you have viewed every row, the grid makes 40,000 calls a second to the dataset to get the data rather than the 400 or so of the cells actually on screen.
Is it possible to somehow setup the grid so that it only actively subscribes to the data that is onscreen at that time? Any suggestions appreciated.
ThanksSteve Mortimer
Hi Steve,
Even though we subscribe to records not in view, I don't understand how it is accessing the data for cells not in view, unless you have set the RecordContainerGenerationMode property to 'PreLoad' or 'LazyLoad' since internally we call CellValuePresenter.FromRecordAndCell and only re-get the cell's value if it returns a non-null value. For RecordContainerGenerationMode 'Recycle' (which is the default) or 'Virtualize' that should only apply to records in view plus possibly a small # of buffered records in the 'Virtualize' case.
Hi Joe, thanks for your respose.
Digging a little deeper and moving the code out into a tester application i think we have moved a little closer to my issue.
You are correct that if we allow the grid to autogenerate the columns the the behaviour is as described. The problem is that we have to generate the columns dynamically as the dataset is really an observable collection of sets of objects. We use reflection at runtime to create UnboundFields and bind into the observable collection of objects.
foreach (PropertyInfo pi in t.GetProperties()){
string bindingPath = string.Format("ColumnSets[{0}].{1}", t.Name, name);
column.Name = name;
column.Label = name;
column.BindingMode = BindingMode.OneWay;
column.DataType = pi.PropertyType;
etc.
So im guessing that this issue is either me not understanding WPF binding, not understanding the correct way of using the grid, or something special about UnboundFields.
Our grid is part of a view which takes a model of data which is extensable via plugins, therefore we dont actually know what columns were going to have until runtime. We did try using a dataset at one point however found its speed slower than an observable collection.
Any ideas on a better way of achieving what we want?
Thanks
Steve
Steve,
I am not clear on why letting the grid autogenerate the fields doesn't work in this scenario. The xamdatagrid will do almost exactly what you are doing in your sample code, with the exception of creating Fields instead of UnboundFields.
Why is this not usable in your scenario?
Hi Joe,
I am replying for my collegue. ColumnSets (as in the example given by Steven - see the binding path) is a collection which contains sets of columns only available at runtime. The problem is the Field object can only bind to a property, and in this case we have to give it a path to the property. Is there a way we can achieve this with the Field class?
Thanks,
Stefan
Hi Stefan,
It was my fault, I didn't look ate the code closely (my brain must have gone on sabbatical).
I understand the problem now. We are lazily creating bindings for the UnboundCells internally but don't clear those bindings as records are scrolled out of view. This problem only affects the cells of UnboundFields.
As long as you are using UnboundFields there is not much you can do until we address the issue in our code.
One approach to get around the problem with the current bits is to have your collection implement the ITypedList interface and have the GetItemProperties method return a collection of derived PropertyDescriptors, a class that you write that e.g. takes the real property descriptor and the model type in the constructor, and then delegates its property and method calls to the real property descriptors. If this is not clear let me know.
The advantage to this approach is that from the xamdatagrid's perspective it will get a collection of propertydescriptors that it can create Fields from thus obviating the need for you to create UnboundFields. I know that it is a bit of a hassle but it is the best solution I can think of with the current bits.
I hope this helps.
That worked out just nice.
Thanks Joe.
As far as the schedule for the next public hotfix, I don't know when that will be. The best way to keep up with the latest hotfixes is thru this blog http://blogs.infragistics.com/tags/Hot+Fix/default.aspx.
As far as filtering and fixed rows is concerned, we don't comment publicly about future features. I can tell you that it is not in the 7.2 version about to be released. I do know that these are features that have been requested by other customers though.
Sorry I can't be more explicit.
Thanks, that is fantastic news. Do you know when the hot fix will be available?
Do you have any news on AutoFilters or fixed rows?
Thanks for your help
I'm not sure why each property is read 3 times. However, for normal fields we don't do any caching of cell values, this is by design. Whenever we need the value we request it from the data item. Unbound cell values are cached and if BindingPath is specified we hook up a standard binding to maintian synchronization.
If the data item implements INotifyPropertyChanged then the DataRecord wires up the INotifyPropertyChange event. If there is no CellValuePresenter in view for the cell being changed then we don't ask for the cell's value from the data item. However there is some minor overhead in just determining that fact. We should unwire the event when the DataRecord is scrolled out of view to eliminate this, I will enter a bug into our system to make sure it gets done.
BTW, the original problem has been fixed, when using UnboundFields we now clear those bindings when the CellValuePresenters are no longer associated with the cell, i.e. they are scrolled out of view. Unfortunately, this fix was made too late to get into the 7.2 release and will have to wait for the next hot fix.
Thanks for your help so far. While this does work i have a noticed that each property is read by the grid 3 times. Any ideas why thats the case?
Also is there any way you can unsubscribe from the INotifyPropertyChanged event when your not activly requiring it?
Our application is still fireing 40,000 events a second even though only 600 or so are actually read (3 times each per event)