Hello,
I recently built a custom class with about 50 properties and bound a List(of My_Property) to a WinGrid. The performance was excruciatingly slow, and after some research I found out that the ultragrid keeps running the code to get the property from the underlying class, even though there hasn't been any changes. I put a Debug.Print statement in one of the properties in my class, and found that the property is calculated twice just when I scroll the WinGrid. Is there any way to tell the WinGrid to only run the property calculation when the grid is initially loaded, and when I explicitly tell it to, rather than having it calculate whenever it feels like it?
Thank you in advance.
P.S. I'd like to avoid using datatables as a datasource since some of the calculations I need to perform in the Data Class is too complex for the datatable's Expressions.
hsarai said:That's surprising, you'd think I'd be able to do something so that it has a change indicator which the grid would use to determine if there are any changes, rather than the grid evaluating every single value of the class on every arbitrary operation such as simply scrolling. Attached has an example of the type of class I'm using to bind to the grid. Please let me know if you need further information.
The alternative would be for the grid to cache the data, which would be a big waste of memory and also create all sorts of synchronization issues. Now imagine if every bound control did this.. or if you bound the same data source to multiple grids and so had the same data cached in multiple places.
If your property getter is performing a calculation, then it seems to me that the most efficient thing to do would be for your data object to cache the value and track when something changes so it only re-calculates it when it needs to.
Here's the attachment. Also, just in case this helps, this is how I'm adding the data to the grid when the form is created.
Public Sub New()
Dim MyBaseData = GenerateBaseData()
'Runs some Linq code and returns an IEnumerable(of BaseDataSource)
Dim LstClass1 As List(Of Class1)
'Based on the iMaxLimit value specified create the rows of Class1
For i = 1 To iMaxLimit
LstClass1.Add(New Class1(i, MyBaseData))
Next
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
UltraGrid1.DataSource = LstClass1
End
Sub
sorry, realized I attached an empty class. I'll upload again soon.
Brian Fallon"]The answer is no because neither the IBindingList interface nor the BindingManager class, which is how the grid communicates with the data source, provides anything like that.
That's surprising, you'd think I'd be able to do something so that it has a change indicator which the grid would use to determine if there are any changes, rather than the grid evaluating every single value of the class on every arbitrary operation such as simply scrolling. Attached has an example of the type of class I'm using to bind to the grid. Please let me know if you need further information.
This is standard procedure for a data consumer; the grid (like any control that is bound to a list of data) uses the PropertyDescriptor.GetValue method to get the value for a given cell. You will probably notice that the grid's performance is perfectly acceptable with a DataTable having the same number of rows and columns, which would indicate that the problem is probably with your property getters. If you are able to attach a sample here we can take a look and analyze it for you.
hsarai said:Is there any way to tell the WinGrid to only run the property calculation when the grid is initially loaded, and when I explicitly tell it to, rather than having it calculate whenever it feels like it?