public object FindIndex(int index) { //WARNING: this method only searches forward GeneratorNode originalNode = m_currentNode; int originalIndex = m_index; int originalSourceDataIndex = m_sourceDataIndex; do { if (index < (m_index + m_currentNode.ItemCount)) { CollectionGeneratorNode itemsNode = m_currentNode as CollectionGeneratorNode; if (itemsNode != null) { return(itemsNode.GetAt(index - m_index)); } else // not an Items Node, then try to move to child... { //if it fails, then quit loop with failure if (!this.MoveToChild()) { break; } } } else { //if we reach this point, it's because the item we are looking //for is not in this node... Try to access the child //No need to check for childs, since the condition above would catch it (childs part of ItemCount). if (this.MoveToNext()) { continue; } //final try, try "advancing" to the next item. if (this.MoveToFollowing()) { continue; } //up to this, we are in an endpoint, we failed. break; } }while(true); m_currentNode = originalNode; m_index = originalIndex; m_sourceDataIndex = originalSourceDataIndex; return(null); }
//Note: this function will not check for the presence of the item in the details for Items nodes. public bool AbsoluteFindItem(object item) { //this method will search through nodes, even those collapsed for the item //finding items can only be done in "forward" direction GeneratorNode originalNode = m_currentNode; int originalIndex = m_index; int originalSourceDataIndex = m_sourceDataIndex; do { CollectionGeneratorNode itemsNode = m_currentNode as CollectionGeneratorNode; if (itemsNode != null) { if (itemsNode.Items.Contains(item)) { return(true); } } //if we reach this point, it's because the item we are looking //for is not in this node... Try to access the child if (this.MoveToChild()) { continue; } //if we reach this point, it's because we have no child... if (this.MoveToNext()) { continue; } //final try, try "advancing" to the next item. if (this.MoveToFollowing()) { continue; } //up to this, we are in an endpoint, we failed. break; } while(true); m_currentNode = originalNode; m_index = originalIndex; m_sourceDataIndex = originalSourceDataIndex; return(false); }
private void SetupCollectionGeneratorNode(CollectionGeneratorNode newNode, GeneratorNode parent, GeneratorNode previous, GeneratorNode next) { if (previous != null) { previous.Next = newNode; } newNode.Previous = previous; if (next != null) { next.Previous = newNode; } newNode.Next = next; this.RegisterNodeCollectionChanged(( INotifyCollectionChanged )newNode.Items, new NotifyCollectionChangedEventHandler(newNode.OnCollectionChanged)); newNode.CollectionChanged += m_itemsChangedHandler; newNode.ExpansionStateChanged += m_expansionStateChangedHandler; if (parent != null) { newNode.AdjustItemCount(newNode.ItemCount); } }
//This method cannot be used for groups. //This method will search for items independently of the Expanded/Collpased status of GroupGeneratorNodes public bool Contains(object item) { bool skipCollectionGeneratorNodeCheck = false; do { HeadersFootersGeneratorNode headersFootersNode = m_currentNode as HeadersFootersGeneratorNode; skipCollectionGeneratorNodeCheck = false; //If the node is a HeadersFootersGeneratorNode, do some specific handling. if (headersFootersNode != null) { //If the item passed to the function is a GroupHeaderFooterItem, then its because we are looking for a GroupHeader/Footer if (item.GetType() == typeof(GroupHeaderFooterItem)) { GroupHeaderFooterItem groupHeaderFooterItem = ( GroupHeaderFooterItem )item; //Determine the parent node/collectionViewGroup GroupGeneratorNode parentGroup = headersFootersNode.Parent as GroupGeneratorNode; if (parentGroup != null) { if (groupHeaderFooterItem.Group == parentGroup.CollectionViewGroup) { if (headersFootersNode.Items.Contains(groupHeaderFooterItem.Template)) { return(true); } } } //If there is no parent node, then its because the current HeadersFootersGeneratorNode is not a GroupHeaders/Footers node (FixedHeaders/Fotoers or Headers/Footers). skipCollectionGeneratorNodeCheck = true; //force skip CollectionGeneratorNode verification, this is to limit amount of job done by loop body. } //If the item passed is not a GroupHeaderFooterItem, not need to do specific processing, reverting to "Common" algo. } if (!skipCollectionGeneratorNodeCheck) { CollectionGeneratorNode collectionNode = m_currentNode as CollectionGeneratorNode; if (collectionNode != null) { // When dealing with a DataView, the DataView's IList's Contains implementation will return false // for a dataRowView which is in edition and was modified even though it is really part of the collection. // Therefore, we must use a for loop of Object.Equals method calls. System.Data.DataRowView dataRowViewItem = item as System.Data.DataRowView; if (dataRowViewItem != null) { IList items = collectionNode.Items; int itemsCount = items.Count; System.Data.DataRow itemDataRow = dataRowViewItem.Row; for (int i = 0; i < itemsCount; i++) { System.Data.DataRowView currentDataRowView = items[i] as System.Data.DataRowView; if ((currentDataRowView != null) && (itemDataRow == currentDataRowView.Row)) { return(true); } } } else { //Since the GetAt() methods can be overriden to compensate for the Expand/Collapse status of Groups // AND the details features, accessing the collection directly prevent pre-processing of the content of the collection node. if (collectionNode.Items.Contains(item)) { //if the item is from a detail, then I don't want to "use" it!!! return(true); } } } } //if we reach this point, it's because the item we are looking //for is not in this node... Try to access the child //Note: Since I want to search independently of the Expand/Collapse status, //pass false to the method to systematically visit childs. if (this.MoveToChild(false)) { continue; } //if we reach this point, it's because we have no child... if (this.MoveToNext()) { continue; } //final try, try "advancing" to the next item. if (this.MoveToFollowing()) { continue; } //up to this, we are in an endpoint, we failed. break; } while(true); return(false); }
//FindItem skips over itemless nodes. public int FindItem(object item) { //finding items can only be done in "forward" direction int retval = -1; GeneratorNode originalNode = m_currentNode; int originalIndex = m_index; int originalSourceDataIndex = m_sourceDataIndex; while (retval == -1) { ItemsGeneratorNode itemsNode = m_currentNode as ItemsGeneratorNode; if (itemsNode != null) { int tmpIndex = itemsNode.Items.IndexOf(item); if (tmpIndex > -1) { tmpIndex += itemsNode.CountDetailsBeforeDataIndex(tmpIndex); //item is directly from this items node... then return the appropriate index! retval = m_index + tmpIndex; break; } else { //if the item is from a detail, then I don't want to "use" it!!! retval = -1; //but continue looping.... to find occurances of this item somewhere else in the tree } } else { CollectionGeneratorNode collectionNode = m_currentNode as CollectionGeneratorNode; if (collectionNode != null) { int tmpIndex = collectionNode.IndexOf(item); if (tmpIndex != -1) { retval = m_index + tmpIndex; break; } } } //if we reach this point, it's because the item we are looking //for is not in this node... Try to access the child if (this.MoveToChild()) { continue; } //if we reach this point, it's because we have no child... if (this.MoveToNext()) { continue; } //final try, try "advancing" to the next item. if (this.MoveToFollowing()) { continue; } //up to this, we are in an endpoint, we failed. break; } if (retval == -1) { m_currentNode = originalNode; m_index = originalIndex; m_sourceDataIndex = originalSourceDataIndex; } return(retval); }