Hi all,
Describing the problem is a bit hard, i hope i will make myself clear...
i have a special need:
We are using UltraWinGrid.UltraGrid control that holds up to 50,000 records simultaneously.
We want to use the filters abilities that the grid offers. I would like to offer my users an ability to define multiple filters definitions and save them in order to reload them and compare their results.
For example: Defining "Filter_1" - column1 bigger than 100
Defining "Filter_2" - column2 smaller than 50 and column3 bigger than 60
I can define each filter and apply it separately on the grid. But i would like to show my user a short summary before displaying the grid that will summerize the number of results per each Filter.
i wanted to add a list box that will show the following information:
Filter_1 (10,234 items)
Filter_2 (32,000 items)
etc.
The only way I've found of doing that is to perform one of the following:
1. Either go through each row and check if the row meets criteria for each filter defined ("Filter_1", "Filter_2") and save counters for the filters.
2. Load the grid with all 50,000 records then apply each filter and save Rows.Count result for each filter.
Both of them are taking a lot of time. I have tested it and using 5 different filters definitions (Filter_1, Filter_2, etc.) takes something like 7 seconds.
This is not applicable for my application, too slow.
is there a faster way to accomplish that? what is the right way for using them?
Thanks in advance,
Shay
Hi Shay,
It seems to me that the only way to determine the count is to actually perform the filtering, and filtering 50,000 records is going to take time. I don't see any way to avoid that entirely.
When you looped through the rows (approach 1), did you loop through the grid rows or the data source rows? Looping through the grid rows requires the grid to create the UltraGridRow objects, and depending on how you are doing it, you might be forcing the creation of the cells, as well. So you might be able to make that code faster by using the GetCellValue method on the row to avoid unnecessarily creating the cell. Or even better, loop through the data source rows and thus leave the grid rows and cells out of it.
Hi Mike,
Thanks for your reply. This is the way i am doing it:
When i want to add a row: I am adding the object through the binding source. On each insertion, i receive the BindingSource.ListChanged event.
Inside this event, using the ListChangedEventArgs argument i am extracting the index of the row in the grid. As follows:
UltraGridRow row = ultraGrid1.Rows.GetRowWithListIndex(e.NewIndex);
And then, using the MeetsCriteria(row) for each condition, I check whether the row applies to the filter or not and count the results.
Is there a way to check the filters without checking it on the grid row?
Thanks again for the reply,
Hi,
GetRowWithListIndex is not very efficient. It does a linear walk through every grid row trying to find a row with a matching ListIndex. So it might be better for you to add the row to the grid in this case, instead of the DataSource. The Addnew method on the band will return you the newly-created grid row directly with no searching needed.
Shay attias said:Is there a way to check the filters without checking it on the grid row?
You could re-factor your MeetsCriteria method so that the method itself gets the DataRow from the grid row and passes that into a method that does the actual examination of the data. Then you could call that same method whenever you had a DataRow instead of a grid row you wanted to check.
I wanted to know if you were able to solve your issue based on Mike's suggestions or you still need help. Please let us know.
i did not understand your answer too much.
If i did understand you, you want me to implement the MeetsCriteria myself?
Basically it is implementing a filtering mechanism by ourselves.
The whole idea was to use the Grid filters abilities so we will not have to check the condition myself.
Moreover, i do not know beforehand what the filters will be. The user defines them by himself.
So this is not a good idea, unless I understood you wrong.
What is the DataRow you are talking about? Is it a datasource row that i can access via the Binding Source?