Hi,
I'm hoping that someone here can give me a sample of the usage of EnsureCalculated. I have a UltraGrid with numerous formulas and qute a few custom summaries. The problem I'm having is that the summaries are throwing exceptions because the values that they are meant to summarize have not been calculated in time. Currently, the CalcManager is set to Asynchronous. If I set it to Synchronous everything works fine, so it's obvious what the problem is. I could keep toggling the CalcFrequency property in code but that seems a bit silly.
Infragistics documentation states:
"By default, calculations are done Asynchronously on a timer. This ensures that the UI thread is not locked up when long or complex calculations are performed. The disadvantage to this mode is that a particular value may not be calculated when it is requested in code. When retrieving a calculated value using Asynchronous mode, you should call the EnsureCalculated method to ensure the value has been calculated."
There's very little discussion of EnsureCalculated in the documentation but what there is makes reference to a parameter of type IUltraCalcReference. My question is this: In the AggregateCustomSummary Method of a custom summary (derived from ICustomSummaryCalculator) how can i derive the IUltraCalcReference of the row being passed in as an argument so that I might use EnsureCalculated to make certain that the appropriate cells have been calculated?
any help would certainly be appreciated
Steve
Hi Steve,
What kinds of things does your ICustomSummaryCalculator need? I assume you are referring to cells within a row of the grid?
It's unusual to mix formula summaries with Custom summaries. You might be better off creating a new function and registering it in the CalcManager. That way, your calculations would be done as part of the Calc network, and they would get processed in order. There's a sample included in the NetAdvantage SDK (under the CalcManager samples which demonstrates how to create your own function library and register it with the CalcManager.
If that's no good, then you will need to determine a way to get the IUltraCalcReference that represents the object you need calculated. Assuming this is an UltraGridCell, then I don't think the CalcReference for a cell is exposed in any obvious way. CalcReferences are deliberately hidden because for the most part, you should never have to deal with them directly. But what you can do is use a static method on the grid called GetReferenceFromContext. You can pass in an UltraGridCell and it will return the IUltraCalcReference for that cell.
But you should be aware that EnsureCalculated doesn't go straight to the item you give it. What it essentially does it cause all calculations to be performed synchronously until the reference you gave it is calculated. It doesn't change the order of calculation, either. So it could lock up your UI thread while it's working, which is the same as setting the CalcFrequency to Synchronous. So you are really better off creating your own function and using that, rather than mixing formulas and custom summaries - if you can.
Thanks for your rapid and informative reply.
Here's what I've found:
EnsureCalculated doesn't seem to work within a CustomSummaryCalculator. I can get the appropriate reference - thanks to your hint about GetReferenceByContext. But EnsureCalculated always returns false (obviously, i've set wait to true). I've even put it in an infinite while Loop, but it never evaluates to true. Interestingly, if I set the CalcManager to Synchronous everything works fine. I'd be glad to send you a code sample. Probably, I'm doing something wrong (although there's no errors thrown) and I would love to see it work.
In regards to using a formula Summary:
The problem is that I need to be able to specify what rows will be used in the Summaries. The FormulaRowIndexSource Property is really what would matter here, not the calculation (which is a simple sum of specific rows), but the FormulaRowIndexSource basically allows you to specify either all rows or visible rows, and that just won't work.
The situation, simplified, is this. Let's say you have multiple job titles on a project, multiple projects in a dept, multiple depts in a division. You're recording hours worked by each job title on each project on a monthly basis - Jan, Feb, Mar etc, 12 columns. A thirteenth column is added to sum the proceeding 12 - sum(Jan, Feb, Mar...). The reason for the CustomSummaries I'm using is this: We have to summarize hours for each job Title, for each dept, for each division. I can do this easily in a CustomSummaryCalculation by examing each row passed into AggregateCustomSummary method, determining from the value in the job title column if the row is one I'm currently summarizing, (there are ten different job titles), and incrementing the subtotal, etc.
It works fine, but the problem, as originally stated, is that if the CalcManager is set to Asynchronous the CustomSummaryCalculator routine starts before the yearly sum formula above - sum(Jan, Feb, Mar...) is finished, nulls are passed to the CustomSummaryCalculators, and blooey.
Which is why I would dearly love to see EnsureCalculated correctly.
Obviously, the above is simplified. The grid is much more extensive than that - 4 years, not one - more hierarchy, but you get the idea.
By the way, the reason I just don't set the CalcManager to Synchronous and leave it there is that when you do GroupBy's in that mode, it takes, literally, forever.
I'm sorry for the length of this. If you want me to continue this through other channels (code samples, etc.) I'd be glad to.
thanks for any help