/// <summary> /// Recursively initialises the results container based on the <paramref name="list"/> and <paramref name="applicationContainer"/>. /// </summary> /// <param name="resultsContainer">A dictionary of results.</param> /// <param name="list">The control list.</param> /// <param name="applicationContainer">The application data.</param> private void InitResultsContainer(Dictionary<string, object> resultsContainer, ControlList list, Dictionary<string, object> applicationContainer) { foreach (Control control in list) { GroupControl groupControl = control as GroupControl; if (groupControl != null) { this.InitResultsContainer(resultsContainer, groupControl.Controls, applicationContainer); } RepeaterControl repeaterControl = control as RepeaterControl; if (repeaterControl != null) { Dictionary<string, object>[] repeaterItems = applicationContainer.GetRepeaterItemsOrDefault(repeaterControl.Name); Dictionary<string, object>[] resultsItems = new Dictionary<string, object>[repeaterItems.Length]; resultsContainer[repeaterControl.Name] = resultsItems; for (int i = 0; i < repeaterItems.Length; i++) { resultsItems[i] = new Dictionary<string, object>(); this.InitResultsContainer(resultsItems[i], repeaterControl.Controls, repeaterItems[i]); } } } }
/// <summary> /// Runs a calculation for all instances of a repeater and adds the result to <paramref name="resultsContainer"/>. /// </summary> /// <param name="control">The calculation to run.</param> /// <param name="relativePath">The relative path to <paramref name="control"/> within <paramref name="resultsContainer"/> and <paramref name="applicationContainer"/>.</param> /// <param name="absolutePath">The absolute path to <paramref name="control"/> from the root of the application data.</param> /// <param name="resultsContainer">A dictionary of results.</param> /// <param name="applicationContainer">The application data container.</param> /// <param name="exceptionList">A list that <see cref="ExpressionEvaluatorException"/>s will be added to before returning to the client.</param> private void CalculateRepeater(CalculationControl control, ApplicationDataPath relativePath, ApplicationDataPath absolutePath, Dictionary<string, object> resultsContainer, Dictionary<string, object> applicationContainer, List<ExpressionEvaluatorException> exceptionList) { if (relativePath.Count == 0) { try { var result = this.Evaluate(control.CalculationExpression, absolutePath); resultsContainer[control.Name] = result; applicationContainer[control.Name] = result; } catch (ExpressionEvaluatorException e) { e.Tag = absolutePath.ToString(control.Name); exceptionList.Add(e); } return; } ApplicationDataPathSegment segment = relativePath.TraverseDown(); Dictionary<string, object>[] repeaterCalculationResults = (Dictionary<string, object>[])resultsContainer[segment.Name]; Dictionary<string, object>[] repeaterApplicationData = applicationContainer.GetRepeaterItemsOrDefault(segment.Name); for (var i = 0; i < repeaterCalculationResults.Length; i++) { segment.Index = i; absolutePath.FirstOrDefault(s => s.Name == segment.Name).Index = segment.Index; this.CalculateRepeater(control, new ApplicationDataPath(relativePath), absolutePath, repeaterCalculationResults[i], repeaterApplicationData[i], exceptionList); } }