private void RecursiveSaveDataGridContextsState(DataGridContext dataGridContext) { var saveRestoreDataGridContextStateVisitor = new SaveRestoreDataGridContextStateVisitor(true, int.MaxValue, m_stopAtFirstCollapsedGroup); saveRestoreDataGridContextStateVisitor.SaveState(dataGridContext as IDataGridContextVisitable); m_dataGridContextsStateDictionary.Add(new WeakDataGridContextKey(dataGridContext), saveRestoreDataGridContextStateVisitor); foreach (var subDataGridContext in dataGridContext.GetChildContextsCore()) { this.RecursiveSaveDataGridContextsState(subDataGridContext); } }
private void RecursiveRestoreDataGridContextsState(DataGridContext dataGridContext) { var weakDataGridContextKey = new WeakDataGridContextKey(dataGridContext); var saveRestoreDataGridContextStateVisitor = default(SaveRestoreDataGridContextStateVisitor); if (m_dataGridContextsStateDictionary.TryGetValue(weakDataGridContextKey, out saveRestoreDataGridContextStateVisitor)) { try { saveRestoreDataGridContextStateVisitor.RestoreState(dataGridContext as IDataGridContextVisitable); } finally { m_dataGridContextsStateDictionary.Remove(weakDataGridContextKey); } } foreach (var subDataGridContext in dataGridContext.GetChildContextsCore()) { this.RecursiveRestoreDataGridContextsState(subDataGridContext); } }
internal void ProcessVisit( DataGridContext sourceContext, int minIndex, int maxIndex, IDataGridContextVisitor visitor, DataGridContextVisitorType visitorType, bool visitDetails, out bool visitWasStopped) { visitWasStopped = false; // This is used only for DataGridContextVisitorType.ItemsBlock var startSourceDataItemIndex = -1; var endSourceDataItemIndex = -1; if (minIndex < 0) { throw DataGridException.Create <ArgumentException>("The minimum index must be greater than or equal to zero.", sourceContext.DataGridControl, "minIndex"); } if ((visitorType & DataGridContextVisitorType.DataGridContext) == DataGridContextVisitorType.DataGridContext) { visitor.Visit(sourceContext, ref visitWasStopped); if (visitWasStopped) { return; } } //Take a shortcut, if the visit is made only for contexts, and there is no child contexts //return right away. var containsDetails = false; foreach (var childContext in sourceContext.GetChildContextsCore()) { containsDetails = true; break; } var processed = false; var current = m_state; while (true) { processed = false; var itemCount = current.Node.ItemCount; //If the whole current node is below the minIndex, jump over it. if ((current.Index + (itemCount - 1)) < minIndex) { processed = true; } //when the index to visit exceeds the range defined, exit the loop. if (current.Index > maxIndex) { break; } var minForNode = Math.Max(0, minIndex - current.Index); // this will give the base offset within the node where to start the visitating! var maxForNode = Math.Min(itemCount - 1, maxIndex - current.Index); //this will five the max offset within this node to visit (protected against overlfow ) if (!processed) { var headersNode = current.Node as HeadersFootersGeneratorNode; if (headersNode != null) { var isHeaderFooter = (headersNode.Parent == null); //If the node is a Headers or Footers node AND the visitorType does not contain HeadersFooters if ((isHeaderFooter) && ((visitorType & DataGridContextVisitorType.HeadersFooters) == DataGridContextVisitorType.HeadersFooters)) { GeneratorNodeHelper.ProcessHeadersNodeVisit(headersNode, sourceContext, minForNode, maxForNode, visitor, ref visitWasStopped); } else if ((!isHeaderFooter) && ((visitorType & DataGridContextVisitorType.GroupHeadersFooters) == DataGridContextVisitorType.GroupHeadersFooters)) { GeneratorNodeHelper.ProcessHeadersNodeVisit(headersNode, sourceContext, minForNode, maxForNode, visitor, ref visitWasStopped); } processed = true; } } if (!processed) { var itemsNode = current.Node as ItemsGeneratorNode; if (itemsNode != null) { if ((visitorType & DataGridContextVisitorType.ItemsBlock) == DataGridContextVisitorType.ItemsBlock) { GeneratorNodeHelper.ProcessItemsNodeBlockVisit( itemsNode, sourceContext, minForNode, maxForNode, visitor, visitorType, visitDetails, containsDetails, current.DataIndex, ref startSourceDataItemIndex, ref endSourceDataItemIndex, ref visitWasStopped); } else if (((visitDetails) && (containsDetails)) || ((visitorType & DataGridContextVisitorType.Items) == DataGridContextVisitorType.Items)) { GeneratorNodeHelper.ProcessItemsNodeVisit( itemsNode, sourceContext, minForNode, maxForNode, visitor, visitorType, visitDetails, current.DataIndex, ref visitWasStopped); } processed = true; } } if (!processed) { var groupNode = current.Node as GroupGeneratorNode; if (groupNode != null) { if ((visitorType & DataGridContextVisitorType.Groups) == DataGridContextVisitorType.Groups) { visitor.Visit( sourceContext, groupNode.CollectionViewGroup, groupNode.NamesTree, groupNode.Level, groupNode.IsExpanded, groupNode.IsComputedExpanded, ref visitWasStopped); } processed = true; } } if (!processed) { throw DataGridException.Create <DataGridInternalException>("Unable to process the visit.", sourceContext.DataGridControl); } if (visitWasStopped) { break; } if (GeneratorNodeHelper.MoveToChild(ref current)) { continue; } if (GeneratorNodeHelper.MoveToFollowing(ref current)) { continue; } break; } if ((visitorType & DataGridContextVisitorType.ItemsBlock) == DataGridContextVisitorType.ItemsBlock) { if (startSourceDataItemIndex != -1) { var stopVisit = false; visitor.Visit(sourceContext, startSourceDataItemIndex, endSourceDataItemIndex, ref stopVisit); visitWasStopped = visitWasStopped || stopVisit; } } m_state = current; this.EnsureState(); }