private void HandleHeaderFooterReplace( HeadersFootersGeneratorNode node, NotifyCollectionChangedEventArgs e ) { //add immediately the number of new items to the "parent" node since the function call right below will remove the number of old items. node.AdjustItemCount( e.NewItems.Count ); this.HandleHeaderFooterRemove( node, e ); }
private bool RemoveGeneratedItems( HeadersFootersGeneratorNode referenceNode, object referenceItem, IList<DependencyObject> removedContainers ) { bool retval = false; //cycle through the list of generated items, and see if any items are generated between the indexes in the removed range. //start from the end so that removing an item will not cause the indexes to shift for( int i = m_genPosToNode.Count - 1; i >= 0; i-- ) { GeneratorNode node = m_genPosToNode[ i ]; //if the item is within the range removed if( node == referenceNode ) { object item = m_genPosToItem[ i ]; if( item.Equals( referenceItem ) ) { DependencyObject container = m_genPosToContainer[ i ]; removedContainers.Add( container ); this.RemoveContainer( container, referenceItem ); retval = true; this.GenPosArraysRemoveAt( i ); break; } } } return retval; }
private void HandleHeaderFooterRemove( HeadersFootersGeneratorNode node, NotifyCollectionChangedEventArgs e ) { bool itemsRemoved = false; node.AdjustItemCount( -e.OldItems.Count ); //if the node is totally expanded if( node.IsComputedExpanded ) { GroupGeneratorNode parentGroup = node.Parent as GroupGeneratorNode; int removeGenPosIndex; int removeIndex; foreach( object item in e.OldItems ) { object realItem = ( parentGroup != null ) ? new GroupHeaderFooterItem( parentGroup.CollectionViewGroup, item ) : item; removeGenPosIndex = m_genPosToItem.IndexOf( realItem ); GeneratorPosition removeGenPos; // If the value is -1, it means the Header/Footer was not realized when the remove occured. if( removeGenPosIndex != -1 ) { removeIndex = m_genPosToIndex[ removeGenPosIndex ]; removeGenPos = new GeneratorPosition( removeGenPosIndex, 0 ); } else { //Since there is no way to get the item's index from the list of generated items, then //compute it based on the node's index and the event args parameters. GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper( node, 0, 0 ); nodeHelper.ReverseCalculateIndex(); removeIndex = nodeHelper.Index + e.OldStartingIndex; removeGenPos = this.GeneratorPositionFromIndex( removeIndex ); } List<DependencyObject> removedContainers = new List<DependencyObject>(); this.RemoveGeneratedItems( node, realItem, removedContainers ); this.SendRemoveEvent( removeGenPos, removeIndex, 1, removedContainers.Count, removedContainers ); itemsRemoved = true; } this.IncrementCurrentGenerationCount( itemsRemoved ); } }
private int GetStickyFooterCountForNode( HeadersFootersGeneratorNode footerNode, int footerNodeIndex ) { return this.GetStickyFooterCountForNode( footerNode, footerNodeIndex, -1, false ); }
private int GetStickyFooterCountForNode( HeadersFootersGeneratorNode footerNode, int footerNodeIndex, int realizedIndex, bool isRealizedIndexPartOfHeaderNode ) { int stickyFooterCount = 0; int footersNodeItemCount = footerNode.ItemCount; for( int i = footersNodeItemCount - 1; i >= 0; i-- ) { if( ( isRealizedIndexPartOfHeaderNode ) && ( footerNodeIndex + i < realizedIndex ) ) { continue; } object item = footerNode.GetAt( i ); GroupHeaderFooterItem? groupHeaderFooterItem = null; if( item is GroupHeaderFooterItem ) groupHeaderFooterItem = ( GroupHeaderFooterItem )item; if( ( groupHeaderFooterItem != null ) && ( !( groupHeaderFooterItem.Value.Group.IsBottomLevel ) || !this.IsGroupExpanded( groupHeaderFooterItem.Value.Group ) ) ) { continue; } stickyFooterCount++; } return stickyFooterCount; }
private List<StickyContainerGenerated> GenerateStickyFootersForNode( HeadersFootersGeneratorNode footerNode, int footerNodeIndex ) { return this.GenerateStickyFootersForNode( footerNode, footerNodeIndex, -1, false ); }
private List<StickyContainerGenerated> GenerateStickyFootersForNode( HeadersFootersGeneratorNode footerNode, int footerNodeIndex, int realizedIndex, bool isRealizedIndexPartOfFooterNode ) { List<StickyContainerGenerated> generatedStickyContainers = new List<StickyContainerGenerated>(); int footersNodeItemCount = footerNode.ItemCount; // The container is already part of the footer. ICustomItemContainerGenerator generator = ( ICustomItemContainerGenerator )this; GeneratorPosition position = generator.GeneratorPositionFromIndex( footerNodeIndex + footersNodeItemCount - 1 ); // In that case, the potential sticky containers are the requested one and bottom. using( generator.StartAt( position, GeneratorDirection.Backward, true ) ) { for( int i = footersNodeItemCount - 1; i >= 0; i-- ) { if( ( isRealizedIndexPartOfFooterNode ) && ( footerNodeIndex + i < realizedIndex ) ) { continue; } object item = footerNode.GetAt( i ); GroupHeaderFooterItem? groupHeaderFooterItem = null; if( item is GroupHeaderFooterItem ) groupHeaderFooterItem = ( GroupHeaderFooterItem )item; if( ( groupHeaderFooterItem != null ) && ( !( groupHeaderFooterItem.Value.Group.IsBottomLevel ) || !this.IsGroupExpanded( groupHeaderFooterItem.Value.Group ) ) ) { this.Skip(); continue; } bool isNewlyRealized; DependencyObject stickyContainer = generator.GenerateNext( out isNewlyRealized ); generatedStickyContainers.Add( new StickyContainerGenerated( stickyContainer, footerNodeIndex + i, isNewlyRealized ) ); } } return generatedStickyContainers; }
private void CleanHeadersFootersNotification( HeadersFootersGeneratorNode node ) { var collection = node.Items as INotifyCollectionChanged; if( collection == null ) return; try { var nodeList = m_headersFootersMapping[ collection ]; nodeList.Remove( node ); if( nodeList.Count == 0 ) { CollectionChangedEventManager.RemoveListener( collection, this ); m_headersFootersMapping.Remove( collection ); } } catch( Exception e ) { throw new DataGridInternalException( e.Message, e, this.DataGridControl ); } }
private List<StickyContainerGenerated> GenerateStickyHeadersForNode( HeadersFootersGeneratorNode headerNode, int headerNodeIndex, int realizedIndex, bool isRealizedIndexPartOfHeaderNode ) { List<StickyContainerGenerated> generatedStickyContainers = new List<StickyContainerGenerated>(); // The container is already part of the header. ICustomItemContainerGenerator generator = ( ICustomItemContainerGenerator )this; GeneratorPosition position = generator.GeneratorPositionFromIndex( headerNodeIndex ); // In that case, the potential sticky containers are the requested one and up. using( generator.StartAt( position, GeneratorDirection.Forward, true ) ) { for( int i = 0; i < headerNode.ItemCount; i++ ) { // If the realized index represent the index of one of the HeaderNode // item, do not process if( ( isRealizedIndexPartOfHeaderNode ) && ( headerNodeIndex + i > realizedIndex ) ) { break; } object item = headerNode.GetAt( i ); GroupHeaderFooterItem? groupHeaderFooterItem = null; if( item is GroupHeaderFooterItem ) groupHeaderFooterItem = ( GroupHeaderFooterItem )item; if( ( groupHeaderFooterItem != null ) && ( !( groupHeaderFooterItem.Value.Group.IsBottomLevel ) || !this.IsGroupExpanded( groupHeaderFooterItem.Value.Group ) ) ) { this.Skip(); continue; } bool isNewlyRealized; DependencyObject stickyContainer = generator.GenerateNext( out isNewlyRealized ); generatedStickyContainers.Add( new StickyContainerGenerated( stickyContainer, headerNodeIndex + i, isNewlyRealized ) ); } } return generatedStickyContainers; }
private void ConfigureHeadersFootersNotification( INotifyCollectionChanged collection, HeadersFootersGeneratorNode node ) { ICollection<HeadersFootersGeneratorNode> nodeList; if( !m_headersFootersMapping.TryGetValue( collection, out nodeList ) ) { nodeList = new HashSet<HeadersFootersGeneratorNode>(); m_headersFootersMapping.Add( collection, nodeList ); CollectionChangedEventManager.AddListener( collection, this ); } nodeList.Add( node ); }
public HeadersFootersGeneratorNode CreateHeadersFootersGeneratorNode( IList collection, GeneratorNode parent, GeneratorNode previous, GeneratorNode next ) { Debug.Assert( collection != null, "collection cannot be null for CreateHeadersFootersGeneratorNode()" ); INotifyCollectionChanged notifyCollection = collection as INotifyCollectionChanged; Debug.Assert( notifyCollection != null, "collection must be a INotifyCollectionChanged for CreateHeadersFootersGeneratorNode()" ); HeadersFootersGeneratorNode node = new HeadersFootersGeneratorNode( collection, parent ); if( previous != null ) { previous.Next = node; } node.Previous = previous; if( next != null ) { next.Previous = node; } node.Next = next; node.ExpansionStateChanged += m_expansionStateChangedHandler; this.ConfigureHeadersFootersNotification( notifyCollection, node ); if( parent != null ) { node.AdjustItemCount( node.ItemCount ); } return node; }
private static void ProcessHeadersNodeVisit( HeadersFootersGeneratorNode headersNode, DataGridContext sourceContext, int minIndex, int maxIndex, IDataGridContextVisitor visitor, ref bool stopVisit ) { for( int i = minIndex; i <= maxIndex; i++ ) { object template = headersNode.GetAt( i ); GroupGeneratorNode groupNode = headersNode.Parent as GroupGeneratorNode; if( groupNode != null ) { visitor.Visit( sourceContext, ( GroupHeaderFooterItem )template, ref stopVisit ); } else { visitor.Visit( sourceContext, ( DataTemplate )template, ref stopVisit ); } if( stopVisit ) break; } }
private void CleanHeadersFootersNotification( HeadersFootersGeneratorNode node ) { INotifyCollectionChanged notifyCollection = node.Items as INotifyCollectionChanged; if( notifyCollection != null ) { try { List<HeadersFootersGeneratorNode> nodeList = m_headersFootersMapping[ notifyCollection ]; nodeList.Remove( node ); if( nodeList.Count == 0 ) { notifyCollection.CollectionChanged -= OnHeadersFootersCollectionChanged; m_headersFootersMapping.Remove( notifyCollection ); } } catch( Exception e ) { throw new DataGridInternalException( e ); } } }
private void ConfigureHeadersFootersNotification( INotifyCollectionChanged notifyCollection, HeadersFootersGeneratorNode node ) { List<HeadersFootersGeneratorNode> nodeList; bool keyFound = m_headersFootersMapping.TryGetValue( notifyCollection, out nodeList ); if( keyFound == false ) { nodeList = new List<HeadersFootersGeneratorNode>(); notifyCollection.CollectionChanged += OnHeadersFootersCollectionChanged; m_headersFootersMapping.Add( notifyCollection, nodeList ); } nodeList.Add( node ); }