public bool InsertAfter(GeneratorNode insert) { if (insert == null) { throw new DataGridInternalException("GeneratorNode is null."); } int insertionCount; int chainLength; GeneratorNode insertLast = GeneratorNodeHelper.EvaluateChain(insert, out insertionCount, out chainLength); if (m_currentNode.Next != null) { m_currentNode.Next.Previous = insertLast; } insertLast.Next = m_currentNode.Next; insert.Previous = m_currentNode; m_currentNode.Next = insert; // Move the current node to the last node inserted if (!this.MoveToNextBy(chainLength)) { throw new DataGridInternalException("Unable to move to the requested generator index."); } return(true); }
public bool MoveToFollowing() { bool retval = false; GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper(m_currentNode, m_index, m_sourceDataIndex); while (!retval) { retval = nodeHelper.MoveToNext(); if (!retval) { if (!nodeHelper.MoveToParent()) { //cannot move to parent and could not move to next, this is the end of the chain. break; } } } if (retval) { m_currentNode = nodeHelper.CurrentNode; m_index = nodeHelper.Index; m_sourceDataIndex = nodeHelper.SourceDataIndex; } return(retval); }
private void NotifyImmediateChildren(bool value) { if (this.Child != null) { GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper(this.Child, 0, 0); //index not important nodeHelper.MoveToEnd(); do { nodeHelper.CurrentNode.NotifyExpansionStateChanged(value); }while(nodeHelper.MoveToPrevious() == true); } }
internal ReadOnlyCollection <Group> GetImmediateUIGroups(int generatorCurrentGeneration) { if ((m_cachedGeneratorCurrentGeneration != generatorCurrentGeneration) || (m_readOnlyImmediateUIGroups == null)) { Debug.WriteLineIf(((m_cachedGeneratorCurrentGeneration != generatorCurrentGeneration) && (m_readOnlyImmediateUIGroups == null)), "Creating Groups collection since generator version differs AND ReadOnlyCollection is null."); Debug.WriteLineIf(((m_cachedGeneratorCurrentGeneration != generatorCurrentGeneration) && (m_readOnlyImmediateUIGroups != null)), "Creating Groups collection since generator version differs."); Debug.WriteLineIf(((m_cachedGeneratorCurrentGeneration == generatorCurrentGeneration) && (m_readOnlyImmediateUIGroups == null)), "Creating Groups collection even if generator version is the same, since ReadOnlyCollection is null."); m_cachedGeneratorCurrentGeneration = generatorCurrentGeneration; // Ensure collections. if (m_immediateUIGroups == null) { Debug.Assert(m_readOnlyImmediateUIGroups == null); m_immediateUIGroups = new Collection <Group>(); m_readOnlyImmediateUIGroups = new ReadOnlyCollection <Group>(m_immediateUIGroups); } else { Debug.Assert(m_readOnlyImmediateUIGroups != null); m_immediateUIGroups.Clear(); } // Recalculate. GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper(this, 0, 0); //index is not important while (nodeHelper.MoveToNext()) { GroupGeneratorNode groupGeneratorNode = nodeHelper.CurrentNode as GroupGeneratorNode; if (groupGeneratorNode == null) { continue; } m_immediateUIGroups.Add(groupGeneratorNode.UIGroup); } } return(m_readOnlyImmediateUIGroups); }
public bool ReverseCalculateIndex() { // index need to be 0, as I will use the value from the index once I backtracked all the way to the root. GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper(this.CurrentNode, 0, 0); while ((nodeHelper.CurrentNode.Previous != null) || (nodeHelper.CurrentNode.Parent != null)) { if (!nodeHelper.MoveToPrevious()) { nodeHelper.MoveToParent(); } } m_index = System.Math.Abs(nodeHelper.Index); m_sourceDataIndex = System.Math.Abs(nodeHelper.SourceDataIndex); return(true); }
public static GeneratorNode EvaluateChain(GeneratorNode chainStart, out int totalChildCount, out int chainLength) { //if we insert a chain of nodes, this GeneratorNodeHelper will help us GeneratorNodeHelper newHelper = new GeneratorNodeHelper(chainStart, 0, 0); //first determine the total number of childs from this "node" totalChildCount = 0; chainLength = 0; do { totalChildCount += newHelper.CurrentNode.ItemCount; chainLength++; }while(newHelper.MoveToNext()); //then, since we moved at the end of the "chain" return(newHelper.CurrentNode); }
public bool MoveBackward() { bool recurseGroup = true; GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper(m_currentNode, m_index, m_sourceDataIndex); do { GroupGeneratorNode groupNode = nodeHelper.CurrentNode as GroupGeneratorNode; if ((groupNode == null) && (nodeHelper.CurrentNode != m_currentNode) && (nodeHelper.CurrentNode.ItemCount != 0)) { m_currentNode = nodeHelper.CurrentNode; m_index = nodeHelper.Index; m_sourceDataIndex = nodeHelper.SourceDataIndex; return(true); } if ((recurseGroup) && (nodeHelper.MoveToChild())) { nodeHelper.MoveToEnd(); continue; } recurseGroup = true; if (nodeHelper.MoveToPrevious()) { continue; } if (nodeHelper.MoveToParent()) { recurseGroup = false; continue; } break; }while(true); return(false); }
internal static HeadersFootersGeneratorNode GetSameLevelFirstHeaderNode(GroupGeneratorNode generatorNode) { HeadersFootersGeneratorNode headerGeneratorNode = null; GroupGeneratorNode parentGroupGeneratorNode = generatorNode.Parent as GroupGeneratorNode; if (parentGroupGeneratorNode == null) { GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper(generatorNode, 0, 0); //index is not important if (nodeHelper.MoveToFirst()) { headerGeneratorNode = nodeHelper.CurrentNode as HeadersFootersGeneratorNode; } } else { headerGeneratorNode = parentGroupGeneratorNode.Child as HeadersFootersGeneratorNode; } return(headerGeneratorNode); }
public bool InsertBefore(GeneratorNode insert) { if (insert == null) { throw new DataGridInternalException("GeneratorNode is null"); } int insertionCount; int chainLength; GeneratorNode insertLast = GeneratorNodeHelper.EvaluateChain(insert, out insertionCount, out chainLength); GeneratorNode previous = m_currentNode.Previous; if (previous != null) { previous.Next = insert; } insert.Previous = previous; m_currentNode.Previous = insertLast; insertLast.Next = m_currentNode; GroupGeneratorNode parentGroup = insert.Parent as GroupGeneratorNode; if (parentGroup != null) { if (parentGroup.Child == m_currentNode) { parentGroup.Child = insert; } } // Move the current to the first item inserted. // No need to change m_index, m_sourceDataIndex since they will still be with the correct value. m_currentNode = insert; return(true); }
public 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 int startSourceDataItemIndex = -1; int endSourceDataItemIndex = -1; if (minIndex < 0) { DataGridException.ThrowSystemException("The minimum index must be greater than or equal to zero.", typeof(ArgumentException), sourceContext.DataGridControl.Name, "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. bool containsDetails = false; foreach (DataGridContext childContext in sourceContext.GetChildContexts()) { containsDetails = true; break; } bool processed = false; do { //resets the flag that indicates if the node was already processed processed = false; int itemCount = this.CurrentNode.ItemCount; //If the whole current node is below the minIndex, jump over it. if ((this.Index + (itemCount - 1)) < minIndex) { processed = true; } //when the index to visit eNequeos the range defined, exit the loop. if (this.Index > maxIndex) { break; } int minForNode = System.Math.Max(0, minIndex - this.Index); // this will give the base offset within the node where to start the visitating! int maxForNode = System.Math.Min(itemCount - 1, maxIndex - this.Index); //this will five the max offset within this node to visit (protected against overlfow ) if (!processed) { HeadersFootersGeneratorNode headersNode = this.CurrentNode as HeadersFootersGeneratorNode; if (headersNode != null) { bool 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) { ItemsGeneratorNode itemsNode = this.CurrentNode as ItemsGeneratorNode; if (itemsNode != null) { if ((visitorType & DataGridContextVisitorType.ItemsBlock) == DataGridContextVisitorType.ItemsBlock) { GeneratorNodeHelper.ProcessItemsNodeBlockVisit( itemsNode, sourceContext, minForNode, maxForNode, visitor, visitorType, visitDetails, containsDetails, m_sourceDataIndex, ref startSourceDataItemIndex, ref endSourceDataItemIndex, ref visitWasStopped); } else if (((visitDetails) && (containsDetails)) || ((visitorType & DataGridContextVisitorType.Items) == DataGridContextVisitorType.Items)) { GeneratorNodeHelper.ProcessItemsNodeVisit( itemsNode, sourceContext, minForNode, maxForNode, visitor, visitorType, visitDetails, m_sourceDataIndex, ref visitWasStopped); } processed = true; } } if (!processed) { GroupGeneratorNode groupNode = this.CurrentNode 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 new DataGridInternalException("Unable to process the visit.", sourceContext.DataGridControl); } if (visitWasStopped) { break; } if (this.MoveToChild()) { continue; } if (this.MoveToFollowing()) { continue; } break; }while(true); //loop is controled by continue and break statements. if ((visitorType & DataGridContextVisitorType.ItemsBlock) == DataGridContextVisitorType.ItemsBlock) { if (startSourceDataItemIndex != -1) { bool stopVisit = false; visitor.Visit(sourceContext, startSourceDataItemIndex, endSourceDataItemIndex, ref stopVisit); visitWasStopped = visitWasStopped || stopVisit; } } }