Example #1
0
 internal ItemsChangedEventArgs(NotifyCollectionChangedAction action,
                                 GeneratorPosition position,
                                 int itemCount,
                                 int itemUICount) : this(action, position, new GeneratorPosition(-1, 0), itemCount, itemUICount)
          
 {
 }
 internal CustomGeneratorChangedEventArgs( NotifyCollectionChangedAction action, GeneratorPosition position, int index, GeneratorPosition oldPosition, int oldIndex, int itemCount, int itemUICount, IList<DependencyObject> removedContainers )
 {
   _action = action;
   _position = position;
   _oldPosition = oldPosition;
   _itemCount = itemCount;
   _itemUICount = itemUICount;
   _index = index;
   _oldIndex = oldIndex;
   m_removedContainers = removedContainers;
 }
		private void CleanUpItems(int minDesiredGenerated, int maxDesiredGenerated) {
			var internalChildren = InternalChildren;
			var itemContainerGenerator = ItemContainerGenerator;
			for (var i = internalChildren.Count - 1; i >= 0; i--) {
				var position = new GeneratorPosition(i, 0);
				var num2 = itemContainerGenerator.IndexFromGeneratorPosition(position);
				if ((num2 >= minDesiredGenerated) && (num2 <= maxDesiredGenerated)) continue;
				itemContainerGenerator.Remove(position, 1);
				RemoveInternalChildRange(i, 1);
			}
		}
Example #4
0
        //------------------------------------------------------
        //
        //  Constructors
        //
        //------------------------------------------------------

        internal ItemsChangedEventArgs(NotifyCollectionChangedAction action,
                                        GeneratorPosition position,
                                        GeneratorPosition oldPosition,
                                        int itemCount,
                                        int itemUICount)
        {
            _action = action;
            _position = position;
            _oldPosition = oldPosition;
            _itemCount = itemCount;
            _itemUICount = itemUICount;
        }
Example #5
0
        protected override Size MeasureOverride(Size availableSize)
        {
            var desiredSize = new Size();
            ItemsControl parent = ItemsControl.GetItemsOwner(this);
            int count = parent != null && parent.HasItems ? parent.Items.Count : 0;

            // Next line needed otherwise ItemContainerGenerator is null (bug in WinFX ?)
            UIElementCollection children = InternalChildren;
            IItemContainerGenerator generator = ItemContainerGenerator;

            if (count == 0)
            {
                generator.RemoveAll();
                if (children.Count > 0) RemoveInternalChildRange(0, children.Count);
                return desiredSize;
            }

            // Get the generator position of the first visible data item
            GeneratorPosition startPos = generator.GeneratorPositionFromIndex(count - 1);
            using (generator.StartAt(startPos, GeneratorDirection.Forward, true))
            {
                bool newlyRealized;
                // Get or create the child
                var child = generator.GenerateNext(out newlyRealized) as UIElement;

                if (child != null)
                {
                    if (newlyRealized)
                    {
                        AddInternalChild(child);
                        generator.PrepareItemContainer(child);
                    }
                    child.Measure(availableSize);
                    desiredSize = child.DesiredSize;
                }
            }

            // Remove all other items than the top one
            for (int i = children.Count - 1; i >= 0; i--)
            {
                var childGeneratorPos = new GeneratorPosition(i, 0);
                int itemIndex = generator.IndexFromGeneratorPosition(childGeneratorPos);
                if (itemIndex == count - 1) continue;
                generator.Remove(childGeneratorPos, 1);
                RemoveInternalChildRange(i, 1);
            }
            return desiredSize;
        }
Example #6
0
        // Token: 0x06006113 RID: 24851 RVA: 0x001B3EF4 File Offset: 0x001B20F4
        private void MoveChildren(GeneratorPosition fromPos, GeneratorPosition toPos, int containerCount)
        {
            if (fromPos == toPos)
            {
                return;
            }
            IItemContainerGenerator generator = base.Generator;
            int num = generator.IndexFromGeneratorPosition(toPos);

            UIElement[] array = new UIElement[containerCount];
            for (int i = 0; i < containerCount; i++)
            {
                UIElement uielement = this._generatedItemsCollection[fromPos.Index + i];
                this.RemoveChild(uielement);
                array[i] = uielement;
            }
            this._generatedItemsCollection.RemoveRange(fromPos.Index, containerCount);
            for (int j = 0; j < containerCount; j++)
            {
                this._generatedItemsCollection.Insert(num + j, array[j]);
            }
        }
        // THE HACK implementation. A copy from Microsofts VirtualizingStackPanel
        void RemoveChildRange(GeneratorPosition position, int itemCount, int itemUICount) {
            if (IsItemsHost) {
                UIElementCollection children = InternalChildren;
                int pos = position.Index;
                if (position.Offset > 0) {
                    // An item is being removed after the one at the index 
                    pos++;
                }

                if (pos < children.Count) {
                    int uiCount = itemUICount;
                    Debug.Assert((itemCount == itemUICount) || (itemUICount == 0),
                        "Both ItemUICount and ItemCount should be equal or ItemUICount should be 0.");
                    if (uiCount > 0) {
                        RemoveInternalChildRange(pos, uiCount);
                        //VirtualizingPanel.RemoveInternalChildRange(children, pos, uiCount);

                        //if (IsVirtualizing && InRecyclingMode) {
                        //_realizedChildren.RemoveRange(pos, uiCount);
                        //}
                    }
                }
            }
        }
Example #8
0
        void OnItemMoved(object item, int oldIndex, int newIndex)
        {
            if (_itemMap == null)
            {
                // reentrant call (from RemoveAllInternal) shouldn't happen,
                // but if it does, don't crash
                Debug.Assert(false, "unexpected reentrant call to OnItemMoved");
                return;
            }

            DependencyObject container = null;    // the corresponding container
            int containerCount = 0;
            UnrealizedItemBlock uib;

            // search for the moved item
            GeneratorPosition position;
            ItemBlock block;
            int offsetFromBlockStart;
            int correctIndex;
            GetBlockAndPosition(item, oldIndex, true, out position, out block, out offsetFromBlockStart, out correctIndex);

            GeneratorPosition oldPosition = position;

            RealizedItemBlock rib = block as RealizedItemBlock;
            if (rib != null)
            {
                containerCount = 1;
                container = rib.ContainerAt(offsetFromBlockStart);
            }

            // remove the item, and remove the block if it's now empty
            MoveItems(block, offsetFromBlockStart + 1, block.ItemCount - offsetFromBlockStart - 1, block, offsetFromBlockStart, 0);
            --block.ItemCount;
            RemoveAndCoalesceBlocksIfNeeded(block);

            //
            // now insert into the new spot.
            //

            position = new GeneratorPosition(-1,0);
            block = _itemMap.Next;
            offsetFromBlockStart = newIndex;
            while (block != _itemMap && offsetFromBlockStart >= block.ItemCount)
            {
                offsetFromBlockStart -= block.ItemCount;
                if (block.ContainerCount > 0)
                {
                    position.Index += block.ContainerCount;
                    position.Offset = 0;
                }
                else
                {
                    position.Offset += block.ItemCount;
                }
                block = block.Next;
            }

            position.Offset += offsetFromBlockStart + 1;

            // if it's an unrealized block, add the item by bumping the count
            uib = block as UnrealizedItemBlock;
            if (uib != null)
            {
                MoveItems(uib, offsetFromBlockStart, 1, uib, offsetFromBlockStart+1, 0);
                ++ uib.ItemCount;
            }

            // if the item can be added to a previous unrealized block, do so
            else if ((offsetFromBlockStart == 0 || block == _itemMap) &&
                    ((uib = block.Prev as UnrealizedItemBlock) != null))
            {
                ++ uib.ItemCount;
            }

            // otherwise, create a new unrealized block
            else
            {
                uib = new UnrealizedItemBlock();
                uib.ItemCount = 1;

                // split the current realized block, if necessary
                if (offsetFromBlockStart > 0 && (rib = block as RealizedItemBlock) != null)
                {
                    RealizedItemBlock newBlock = new RealizedItemBlock();
                    MoveItems(rib, offsetFromBlockStart, rib.ItemCount - offsetFromBlockStart, newBlock, 0, offsetFromBlockStart);
                    newBlock.InsertAfter(rib);
                    position.Index += block.ContainerCount;
                    position.Offset = 1;
                    offsetFromBlockStart = 0;
                    block = newBlock;
                }

                uib.InsertBefore(block);
            }

            DependencyObject parent = VisualTreeHelper.GetParentInternal(container);

            // tell layout what happened
            if (ItemsChanged != null)
            {
                ItemsChanged(this, new ItemsChangedEventArgs(NotifyCollectionChangedAction.Move, position, oldPosition, 1, containerCount));
            }

            // unhook the container.  Do this after layout has (presumably) removed it from
            // the UI, so that it doesn't inherit DataContext falsely.
            if (container != null)
            {
                if (parent == null || VisualTreeHelper.GetParentInternal(container) != parent)
                {
                    UnlinkContainerFromItem(container, item);
                }
                else
                {
                    // If the container has the same visual parent as before then that means that
                    // the container was just repositioned within the parent's VisualCollection.
                    // we don't need to unlink the container, but we do need to re-realize the block.
                    Realize(uib, offsetFromBlockStart, item, container);
                }
            }

            // fix up the AlternationIndex on containers affected by the move
            if (_alternationCount > 0)
            {
                // start with the smaller of the two positions, and proceed forward.
                // This tends to preserve the AlternatonIndex on containers at the
                // front of the list, as users expect
                int index = Math.Min(oldIndex, newIndex);
                GetBlockAndPosition(index, out position, out block, out offsetFromBlockStart);
                SetAlternationIndex(block, offsetFromBlockStart, GeneratorDirection.Forward);
            }
        }
Example #9
0
        void GetBlockAndPosition(object item, bool deletedFromItems, out GeneratorPosition position, out ItemBlock block, out int offsetFromBlockStart, out int correctIndex)
        {
            correctIndex = 0;
            int containerIndex = 0;
            offsetFromBlockStart = 0;
            int deletionOffset = deletedFromItems ? 1 : 0;
            position = new GeneratorPosition(-1, 0);

            if (_itemMap == null)
            {
                // handle reentrant call
                block = null;
                return;
            }

            for (block = _itemMap.Next;  block != _itemMap;  block = block.Next)
            {
                UnrealizedItemBlock uib;
                RealizedItemBlock rib = block as RealizedItemBlock;

                if (rib != null)
                {
                    // compare realized items with item for which we are searching
                    offsetFromBlockStart = rib.OffsetOfItem(item);
                    if (offsetFromBlockStart >= 0)
                    {
                        position = new GeneratorPosition(containerIndex + offsetFromBlockStart, 0);
                        correctIndex += offsetFromBlockStart;
                        break;
                    }
                }
                else if ((uib = block as UnrealizedItemBlock) != null)
                {
                    // if the item isn't realized, we can't find it
                    // directly.  Instead, look for indirect evidence that it
                    // belongs to this block by checking the indices of
                    // nearby realized items.

#if DEBUG
                    // Sanity check - make sure data structure is OK so far.
                    rib = block.Prev as RealizedItemBlock;
                    if (rib != null && rib.ContainerCount > 0)
                    {
                        Debug.Assert(Object.Equals(rib.ItemAt(rib.ContainerCount - 1),
                                                    ItemsInternal[correctIndex - 1]),
                                    "Generator data structure is corrupt");
                    }
#endif

                    bool itemIsInCurrentBlock = false;
                    rib = block.Next as RealizedItemBlock;
                    if (rib != null && rib.ContainerCount > 0)
                    {
                        // if the index of the next realized item is off by one,
                        // the deleted item likely comes from the current
                        // unrealized block.
                        itemIsInCurrentBlock =
                                Object.Equals(rib.ItemAt(0),
                                    ItemsInternal[correctIndex + block.ItemCount - deletionOffset]);
                    }
                    else if (block.Next == _itemMap)
                    {
                        // similarly if we're at the end of the list and the
                        // overall count is off by one, or if the current block
                        // is the only block, the deleted item likely
                        // comes from the current (last) unrealized block
                        itemIsInCurrentBlock = block.Prev == _itemMap ||
                            (ItemsInternal.Count == correctIndex + block.ItemCount - deletionOffset);
                    }

                    if (itemIsInCurrentBlock)
                    {
                        // we don't know where it is in this block, so assume
                        // it's the very first item.
                        offsetFromBlockStart = 0;
                        position = new GeneratorPosition(containerIndex-1, 1);
                        break;
                    }
                }

                correctIndex += block.ItemCount;
                containerIndex += block.ContainerCount;
            }

            if (block == _itemMap)
            {
                // There's no way of knowing which unrealized block it belonged to, so
                // the data structure can't be updated correctly.  Sound the alarm.
                throw new InvalidOperationException(SR.Get(SRID.CannotFindRemovedItem));
            }
        }
Example #10
0
        // Called when an item is added to the items collection
        void OnItemAdded(object item, int index)
        {
            if (_itemMap == null)
            {
                // reentrant call (from RemoveAllInternal) shouldn't happen,
                // but if it does, don't crash
                Debug.Assert(false, "unexpected reentrant call to OnItemAdded");
                return;
            }

            ValidateAndCorrectIndex(item, ref index);

            GeneratorPosition position = new GeneratorPosition(-1,0);

            // find the block containing the new item
            ItemBlock block = _itemMap.Next;
            int offset = index;
            while (block != _itemMap && offset >= block.ItemCount)
            {
                offset -= block.ItemCount;
                position.Index += block.ContainerCount;
                block = block.Next;
            }

            position.Offset = offset + 1;

            // if it's an unrealized block, add the item by bumping the count
            UnrealizedItemBlock uib = block as UnrealizedItemBlock;
            if (uib != null)
            {
                MoveItems(uib, offset, 1, uib, offset+1, 0);
                ++ uib.ItemCount;
            }

            // if the item can be added to a previous unrealized block, do so
            else if ((offset == 0 || block == _itemMap) &&
                    ((uib = block.Prev as UnrealizedItemBlock) != null))
            {
                ++ uib.ItemCount;
            }

            // otherwise, create a new unrealized block
            else
            {
                uib = new UnrealizedItemBlock();
                uib.ItemCount = 1;

                // split the current realized block, if necessary
                RealizedItemBlock rib;
                if (offset > 0 && (rib = block as RealizedItemBlock) != null)
                {
                    RealizedItemBlock newBlock = new RealizedItemBlock();
                    MoveItems(rib, offset, rib.ItemCount - offset, newBlock, 0, offset);
                    newBlock.InsertAfter(rib);
                    position.Index += block.ContainerCount;
                    position.Offset = 1;
                    block = newBlock;
                }

                uib.InsertBefore(block);
            }

            // tell generators what happened
            if (MapChanged != null)
            {
                MapChanged(null, index, +1, uib, 0, 0);
            }

            // tell layout what happened
            if (ItemsChanged != null)
            {
                ItemsChanged(this, new ItemsChangedEventArgs(NotifyCollectionChangedAction.Add, position, 1, 0));
            }
        }
Example #11
0
 void GetBlockAndPosition(object item, int itemIndex, bool deletedFromItems, out GeneratorPosition position, out ItemBlock block, out int offsetFromBlockStart, out int correctIndex)
 {
     if (itemIndex >= 0)
     {
         GetBlockAndPosition(itemIndex, out position, out block, out offsetFromBlockStart);
         correctIndex = itemIndex;
     }
     else
     {
         GetBlockAndPosition(item, deletedFromItems, out position, out block, out offsetFromBlockStart, out correctIndex);
     }
 }
Example #12
0
        void GetBlockAndPosition(int itemIndex, out GeneratorPosition position, out ItemBlock block, out int offsetFromBlockStart)
        {
            position = new GeneratorPosition(-1, 0);
            block = null;
            offsetFromBlockStart = itemIndex;

            if (_itemMap == null || itemIndex < 0)
                return;

            int containerIndex = 0;

            for (block = _itemMap.Next;  block != _itemMap;  block = block.Next)
            {
                if (offsetFromBlockStart >= block.ItemCount)
                {
                    // item belongs to a later block, increment the containerIndex
                    containerIndex += block.ContainerCount;
                    offsetFromBlockStart -= block.ItemCount;
                }
                else
                {
                    // item belongs to this block.  Determine the container index and offset
                    if (block.ContainerCount > 0)
                    {
                        // block has realized items
                        position = new GeneratorPosition(containerIndex + offsetFromBlockStart, 0);
                    }
                    else
                    {
                        // block has unrealized items
                        position = new GeneratorPosition(containerIndex-1, offsetFromBlockStart+1);
                    }

                    break;
                }
            }
        }
Example #13
0
        // Called when the items collection is refreshed
        void OnRefresh()
        {
            ((IItemContainerGenerator)this).RemoveAll();

            // tell layout what happened
            if (ItemsChanged != null)
            {
                GeneratorPosition position = new GeneratorPosition(0, 0);
                ItemsChanged(this, new ItemsChangedEventArgs(NotifyCollectionChangedAction.Reset, position, 0, 0));
            }
        }
    private GeneratorPosition FindPreviousUnrealizedGeneratorPosition( GeneratorPosition position )
    {
      int index = this.IndexFromGeneratorPosition( position ) - 1;

      while( index >= 0 )
      {
        if( !m_genPosToIndex.Contains( index ) )
        {
          break;
        }

        index--;
      }

      GeneratorPosition retval = this.GeneratorPositionFromIndex( index );

      return retval;
    }
        /// <summary>
        /// Arrange Override
        /// </summary>
        protected override Size ArrangeOverride(Size finalSize)
        {
            // monitors changes to the ScrollViewer extent value
            if (_oldExtent != _extent)
            {
                _oldExtent = _extent;
                if (_scrollOwner != null)
                    _scrollOwner.InvalidateScrollInfo();
            }

            // monitors changes to the parent container size, (ie window resizes)
            if (finalSize != _lastSize)
            {
                _lastSize = finalSize;
                if (_scrollOwner != null)
                    _scrollOwner.InvalidateScrollInfo();
            }

            // monitor scrolling being removed
            bool invalidateMeasure = false;
            if (_extent.Width <= _viewPort.Width && _offset.X > 0)
            {
                _offset.X = 0;
                _translateTransform.X = 0;

                if (_scrollOwner != null)
                    _scrollOwner.InvalidateScrollInfo();

                invalidateMeasure = true;
            }
            if (_extent.Height <= _viewPort.Height && _offset.Y > 0)
            {
                _offset.Y = 0;
                _translateTransform.Y = 0;

                if (_scrollOwner != null)
                    _scrollOwner.InvalidateScrollInfo();

                invalidateMeasure = true;
            }
            if (invalidateMeasure)
                InvalidateMeasure();



            // arrange the children
            double leftOrTop = 0;
            for (int i = 0; i < InternalChildren.Count; i++)
            {
                UIElement child = InternalChildren[i];

                GeneratorPosition childGeneratorPos = new GeneratorPosition(i, 0);
                int itemIndex = this.ItemContainerGenerator.IndexFromGeneratorPosition(childGeneratorPos);

                child.Arrange(_childRects[itemIndex]);

                leftOrTop += (_tabStripPlacement == Dock.Top || _tabStripPlacement == Dock.Bottom) ? _childRects[i].Width : _childRects[i].Height;
            }


            // we need these lines as when the Scroll Buttons get Shown/Hidden,
            // the _offset value gets out of line, this will ensure that our scroll position stays in line
            if (InternalChildren.Count > 0)
            {
                _offset = _childRects[FirstVisibleIndex].TopLeft;
                _translateTransform.X = -_offset.X;
                _translateTransform.Y = -_offset.Y;
            }

            return finalSize;
        }
        protected override Size MeasureOverride(Size availableSize)
        {
            Size desiredSize = new Size();
            UIElementCollection children = InternalChildren;
            IItemContainerGenerator generator = ItemContainerGenerator;

            int itemsCount = 0;
            if (generator != null)
            {
                int StartItemIndex = navigationPane.GetFirstItemIndex(DisplayType);
                if (StartItemIndex > -1)
                {
                    int maxItems = DisplayType == NavigationPaneItemDisplayType.Large ? navigationPane.LargeItems : int.MaxValue;
                    GeneratorPosition startPos = new GeneratorPosition(-1, StartItemIndex + 1);

                    using (generator.StartAt(startPos, GeneratorDirection.Forward, true))
                    {
                        bool sizeExceeded = false;

                        bool newlyRealized;
                        UIElement child = null;

              // temp fix for {Disconnected Item}
              // needs more inspecting and documentation to fix it correctly !!
              // but this for now seems to work... strange items present ??
              // remove them, NOW !!!!!
              //for (int j = children.Count - 1; j > -1; j--)
              //{
               //UIElement item = children[j];
               //object o = navigationPane.ItemContainerGenerator.ItemFromContainer(item);
               //if (o == DependencyProperty.UnsetValue)
               // RemoveInternalChild(item);
              //}

                        while (!sizeExceeded && (itemsCount < maxItems) && (child = generator.GenerateNext(out newlyRealized) as UIElement) != null)
                        {
                            bool isExcluded = NavigationPane.GetIsItemExcluded(child);
                            if (!isExcluded)
                            {
                                if (newlyRealized || !children.Contains(child))
                                {
                                    int absoluteIndex = StartItemIndex + itemsCount;
                                    int index = GetInsertIndex(absoluteIndex);

             if (absoluteIndex < 9 && navigationPane.ItemsKeyAuto)
             {
              NavigationPaneItem f = child as NavigationPaneItem;
              {
               Window w = Window.GetWindow(child);
               if (w != null)
               {
            KeyBinding binding = f.keyBinding;
            if (binding != null)
             w.InputBindings.Remove(binding);

            f.keyBinding = new KeyBinding(NavigationPane.SelectItemCommand, Key.D1 + absoluteIndex, navigationPane.ItemsKeyModifiers);
            f.keyBinding.CommandParameter = child;
            f.keyBinding.CommandTarget = navigationPane;
            w.InputBindings.Add(f.keyBinding);

            if (f != null)
             f.Gesture = (f.keyBinding.Gesture as KeyGesture).GetDisplayStringForCulture(CultureInfo.CurrentCulture);
               }
              }
             }
                                    SetActivePanel(child, this);
                                    SetAbosluteIndex(child, absoluteIndex);
                                    SetItemDisplayType(child, DisplayType);

                                    if (newlyRealized)
                                        generator.PrepareItemContainer(child);

             InsertInternalChild(index, child);
                                }

                                #region measurament algoritm
                                Size childSize = new Size();
                                if (Orientation == Orientation.Vertical)
                                    childSize = new Size(availableSize.Width, double.PositiveInfinity);
                                else
                                    childSize = new Size(double.PositiveInfinity, availableSize.Height);

                                child.Measure(childSize);

                                if (Orientation == Orientation.Vertical)
                                {
                                    sizeExceeded = desiredSize.Height + child.DesiredSize.Height > availableSize.Height;
                                    if (!sizeExceeded)
                                    {
                                        desiredSize.Width = Math.Max(desiredSize.Width, child.DesiredSize.Width);
                                        desiredSize.Height += child.DesiredSize.Height;
                                    }
                                }
                                else
                                {
                                    sizeExceeded = desiredSize.Width + child.DesiredSize.Width > availableSize.Width;
                                    if (!sizeExceeded)
                                    {
                                        desiredSize.Width += child.DesiredSize.Width;
                                        desiredSize.Height = Math.Max(desiredSize.Height, child.DesiredSize.Height);
                                    }
                                }
                                #endregion

                                if (!sizeExceeded)
                                    itemsCount++;
                            }
                            else
                            {
                                RemoveInternalChild(child);
                            }
                        }
                    }
                    CleanUpItems(StartItemIndex, itemsCount);
                }
            }

            if(DisplayType == NavigationPaneItemDisplayType.Small)
                navigationPane.SmallItems = itemsCount;
            return desiredSize;
        }
      public CustomItemContainerGeneratorDisposableDisposer( CustomItemContainerGenerator generator, GeneratorPosition startGenPos, GeneratorDirection direction )
      {
        if( generator == null )
        {
          throw new ArgumentNullException( "generator" );
        }

        m_generator = generator;

        m_generator.StartGenerator( startGenPos, direction );
      }
Example #18
0
 private void CleanUpItems(int minDesiredGenerated, int maxDesiredGenerated)
 {
     var generator = ItemContainerGenerator;
     for (var i = InternalChildren.Count - 1; i >= 0; i--)
     {
         var childGeneratorPos = new GeneratorPosition(i, 0);
         var itemIndex = generator.IndexFromGeneratorPosition(childGeneratorPos);
         if (itemIndex < minDesiredGenerated || itemIndex > maxDesiredGenerated)
         {
             RemoveInternalChildRange(i, 1);
             generator.Remove(childGeneratorPos, 1);
         }
     }
 }
    private GeneratorPosition ConvertDetailGeneratorPosition( GeneratorPosition referencePosition, object masterItem, DetailGeneratorNode detailNode, out int globalIndex )
    {
      //If the requested generator position map past at least one generated item from the detail generator, then the job is easy...
      if( referencePosition.Index >= 0 )
      {
        int generatorIndex = this.FindGeneratorIndexForNode( detailNode, referencePosition.Index );

        // Ensure to return the globalIndex as -1
        // if the generator index is not found for
        // a DetailNode. This can occur if a Detail
        // is filtered out via AutoFiltering.
        globalIndex = ( generatorIndex > -1 )
          ? m_genPosToIndex[ generatorIndex ]
          : globalIndex = -1;

        return new GeneratorPosition( generatorIndex, referencePosition.Offset );
      }
      else
      {
        //This means the GeneratorPosition returned by the DetailGenerator is "before" any generated item from the detail generator.
        //I need more complex detection of the GeneratorPosition.

        // First - Get the Index of the MasterItem
        int masterIndex = this.IndexFromItem( masterItem );

        //Second - Get the DetailGenerator's Index for the DetailGenerator's GenPos
        int detailGeneratorIndex = detailNode.DetailGenerator.IndexFromGeneratorPosition( referencePosition );

        globalIndex = masterIndex + detailGeneratorIndex + 1;

        // Finally - Have the Master Generator compute the GeneratorPosition from the sum of both
        return this.GeneratorPositionFromIndex( globalIndex );
      }
    }
    private void RemoveDetailContainers( GeneratorPosition convertedGeneratorPosition, int removeCount )
    {
      int removeGenPosIndex = convertedGeneratorPosition.Index;
      if( convertedGeneratorPosition.Offset > 0 )
      {
        removeGenPosIndex++;
      }

      for( int i = 0; i < removeCount; i++ )
      {
        this.GenPosArraysRemoveAt( removeGenPosIndex );
      }
    }
    private void HandleDetailReset( object masterItem, DetailGeneratorNode detailNode )
    {
      GeneratorNodeHelper nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 );
      int masterIndex = nodeHelper.FindItem( masterItem );

      // -1 means either taht the master item is below a collapsed group node, or that the item does not exists, validate.
      if( masterIndex == -1 )
      {
        nodeHelper = new GeneratorNodeHelper( m_startNode, 0, 0 );
        if( !nodeHelper.Contains( masterItem ) )
          throw new DataGridInternalException();
      }

      ItemsGeneratorNode masterNode = nodeHelper.CurrentNode as ItemsGeneratorNode;

      Debug.Assert( masterNode != null, "masterNode != null" );
#if LOG
      Log.Assert( this, masterNode != null, "masterNode != null" );
#endif

      //start index will be ignored later on if the masterIndex is -1!!
      int startIndex = nodeHelper.Index + masterNode.IndexOf( masterItem ) + 1; //details start a master index + 1

      List<DetailGeneratorNode> detailsForMaster = null;

      //edge case, it is possible to receive a Reset from Floating details!
      if( masterNode.Details == null )
      {
        //check for floating details, if not present, throw, this is an abnormal case.
        if( !m_floatingDetails.Contains( masterItem ) )
        {
          throw new DataGridInternalException();
        }
      }
      else
      {
        masterNode.Details.TryGetValue( masterNode.Items.IndexOf( masterItem ), out detailsForMaster );

        Debug.Assert( detailsForMaster != null, "detailsForMaster != null" );
#if LOG
        Log.Assert( this, detailsForMaster != null, "detailsForMaster != null" );
#endif
      }

      if( detailsForMaster != null )
      {
        //this is required to ensure that if the details that resets is not the first one, the index is calculated appropriatly.
        foreach( DetailGeneratorNode node in detailsForMaster )
        {
          if( node == detailNode )
          {
            break;
          }
          else
          {
            startIndex += node.ItemCount;
          }
        }

        //if there were 'items' in the detail node, process the remove of them
        int oldDetailCount = detailNode.ItemCount;
        if( oldDetailCount > 0 )
        {
          int endIndex = startIndex + oldDetailCount - 1; //last detail index

          GeneratorPosition removeGenPos = ( masterIndex != -1 )
            ? this.GeneratorPositionFromIndex( startIndex )
            : new GeneratorPosition( -1, 1 );

          int genRemCount = 0;

          List<DependencyObject> removedContainers = new List<DependencyObject>();

          //this has no uses if the masterIndex is -1 ( collapsed master item )
          if( masterIndex != -1 )
          {
            genRemCount = this.RemoveGeneratedItems( startIndex, endIndex, removedContainers );
          }

          masterNode.AdjustItemCount( -oldDetailCount );

          this.IncrementCurrentGenerationCount();

          //this has no uses if the masterIndex is -1 ( collapsed master item )
          if( masterIndex != -1 )
          {
            this.SendRemoveEvent( removeGenPos, masterIndex + 1, oldDetailCount, genRemCount, removedContainers );
          }
        }

        detailNode.UpdateItemCount();

        int newDetailCount = detailNode.ItemCount;
        if( newDetailCount > 0 )
        {
          GeneratorPosition addGenPos = new GeneratorPosition( -1, 1 );

          //this has no uses if the masterIndex is -1 ( collapsed master item )
          if( masterIndex != -1 )
          {
            addGenPos = this.GeneratorPositionFromIndex( startIndex );
          }

          masterNode.AdjustItemCount( newDetailCount );

          this.IncrementCurrentGenerationCount();

          //this has no uses if the masterIndex is -1 ( collapsed master item )
          if( masterIndex != -1 )
          {
            this.SendAddEvent( addGenPos, masterIndex + 1, newDetailCount );
          }
        }
      }
    }
Example #22
0
 /// <summary>
 /// Remove generated elements.
 /// </summary>
 void IItemContainerGenerator.Remove(GeneratorPosition position, int count)
 {
     Remove(position, count, /*isRecycling = */ false);
 }
Example #23
0
        /// <summary>
        /// Map a GeneratorPosition to an index into the items collection.
        /// </summary>
        int IItemContainerGenerator.IndexFromGeneratorPosition(GeneratorPosition position)
        {
            int index = position.Index;

            if (index == -1)
            {
                // offset is relative to the fictitious boundary item
                if (position.Offset >= 0)
                {
                    return position.Offset - 1;
                }
                else
                {
                    return ItemsInternal.Count + position.Offset;
                }
            }

            if (_itemMap != null)
            {
                int itemIndex = 0;      // number of items we've skipped over

                // locate container at the given index
                for (ItemBlock block = _itemMap.Next;  block != _itemMap;  block = block.Next)
                {
                    if (index < block.ContainerCount)
                    {
                        // container is within this block.  return the answer
                        return itemIndex + index + position.Offset;
                    }
                    else
                    {
                        // skip over this block
                        itemIndex += block.ItemCount;
                        index -= block.ContainerCount;
                    }
                }
            }

            return -1;
        }
Example #24
0
        /// <summary>
        /// Remove generated elements.
        /// </summary>
        private void Remove(GeneratorPosition position, int count, bool isRecycling)
        {
            if (position.Offset != 0)
                throw new ArgumentException(SR.Get(SRID.RemoveRequiresOffsetZero, position.Index, position.Offset), "position");
            if (count <= 0)
                throw new ArgumentException(SR.Get(SRID.RemoveRequiresPositiveCount, count), "count");

            if (_itemMap == null)
            {
                // ignore reentrant call (during RemoveAllInternal)
                Debug.Assert(false, "Unexpected reentrant call to ICG.Remove");
                return;
            }

            int index = position.Index;
            ItemBlock block;

            // find the leftmost item to remove
            int offsetL = index;
            for (block = _itemMap.Next;  block != _itemMap;  block = block.Next)
            {
                if (offsetL < block.ContainerCount)
                    break;

                offsetL -= block.ContainerCount;
            }
            RealizedItemBlock blockL = block as RealizedItemBlock;

            // find the rightmost item to remove
            int offsetR = offsetL + count - 1;
            for (; block != _itemMap;  block = block.Next)
            {
                if (!(block is RealizedItemBlock))
                    throw new InvalidOperationException(SR.Get(SRID.CannotRemoveUnrealizedItems, index, count));

                if (offsetR < block.ContainerCount)
                    break;

                offsetR -= block.ContainerCount;
            }
            RealizedItemBlock blockR = block as RealizedItemBlock;

            // de-initialize the containers that are being removed
            RealizedItemBlock rblock = blockL;
            int offset = offsetL;
            while (rblock != blockR || offset <= offsetR)
            {
                DependencyObject container = rblock.ContainerAt(offset);

                UnlinkContainerFromItem(container, rblock.ItemAt(offset));
                // DataGrid generates non-GroupItem for NewItemPlaceHolder
                // Dont recycle in this case.
                bool isNewItemPlaceHolderWhenGrouping = _generatesGroupItems && !(container is GroupItem);

                if (isRecycling && !isNewItemPlaceHolderWhenGrouping)
                {
                    Debug.Assert(!_recyclableContainers.Contains(container), "trying to add a container to the collection twice");

                    if (_containerType == null)
                    {
                        _containerType = container.GetType();
                    }
                    else if (_containerType != container.GetType())
                    {
                        throw new InvalidOperationException(SR.Get(SRID.CannotRecyleHeterogeneousTypes));
                    }

                    _recyclableContainers.Enqueue(container);
                }

                if (++offset >= rblock.ContainerCount && rblock != blockR)
                {
                    rblock = rblock.Next as RealizedItemBlock;
                    offset = 0;
                }
            }

            // see whether the range hits the edge of a block on either side,
            // and whether the a`butting block is an unrealized gap
            bool edgeL = (offsetL == 0);
            bool edgeR = (offsetR == blockR.ItemCount-1);
            bool abutL = edgeL && (blockL.Prev is UnrealizedItemBlock);
            bool abutR = edgeR && (blockR.Next is UnrealizedItemBlock);

            // determine the target (unrealized) block,
            // the offset within the target at which to insert items,
            // and the intial change in cumulative item count
            UnrealizedItemBlock blockT;
            ItemBlock predecessor = null;
            int offsetT;
            int deltaCount;

            if (abutL)
            {
                blockT = (UnrealizedItemBlock)blockL.Prev;
                offsetT = blockT.ItemCount;
                deltaCount = -blockT.ItemCount;
            }
            else if (abutR)
            {
                blockT = (UnrealizedItemBlock)blockR.Next;
                offsetT = 0;
                deltaCount = offsetL;
            }
            else
            {
                blockT = new UnrealizedItemBlock();
                offsetT = 0;
                deltaCount = offsetL;

                // remember where the new block goes, so we can insert it later
                predecessor = (edgeL) ? blockL.Prev : blockL;
            }

            // move items within the range to the target block
            for (block = blockL;  block != blockR;  block = block.Next)
            {
                int itemCount = block.ItemCount;
                MoveItems(block, offsetL, itemCount-offsetL,
                            blockT, offsetT, deltaCount);
                offsetT += itemCount-offsetL;
                offsetL = 0;
                deltaCount -= itemCount;
                if (block.ItemCount == 0)
                    block.Remove();
            }

            // the last block in the range is a little special...
            // Move the last unrealized piece.
            int remaining = block.ItemCount - 1 - offsetR;
            MoveItems(block, offsetL, offsetR - offsetL + 1,
                        blockT, offsetT, deltaCount);

            // Move the remaining realized items
            RealizedItemBlock blockX = blockR;
            if (!edgeR)
            {
                if (blockL == blockR && !edgeL)
                {
                    blockX = new RealizedItemBlock();
                }

                MoveItems(block, offsetR+1, remaining,
                            blockX, 0, offsetR+1);
            }

            // if we created any new blocks, insert them in the list
            if (predecessor != null)
                blockT.InsertAfter(predecessor);
            if (blockX != blockR)
                blockX.InsertAfter(blockT);

            RemoveAndCoalesceBlocksIfNeeded(block);

        }
Example #25
0
 // Token: 0x06005E4F RID: 24143 RVA: 0x001A7404 File Offset: 0x001A5604
 internal ItemsChangedEventArgs(NotifyCollectionChangedAction action, GeneratorPosition position, GeneratorPosition oldPosition, int itemCount, int itemUICount)
 {
     this._action      = action;
     this._position    = position;
     this._oldPosition = oldPosition;
     this._itemCount   = itemCount;
     this._itemUICount = itemUICount;
 }
Example #26
0
 void IRecyclingItemContainerGenerator.Recycle(GeneratorPosition position, int count)
 {
     Remove(position, count, /*isRecyling = */ true);
 }
Example #27
0
 // Token: 0x06005E50 RID: 24144 RVA: 0x001A7431 File Offset: 0x001A5631
 internal ItemsChangedEventArgs(NotifyCollectionChangedAction action, GeneratorPosition position, int itemCount, int itemUICount) : this(action, position, new GeneratorPosition(-1, 0), itemCount, itemUICount)
 {
 }
Example #28
0
            //------------------------------------------------------
            //
            //  Constructors
            //
            //------------------------------------------------------

            internal Generator(ItemContainerGenerator factory, GeneratorPosition position, GeneratorDirection direction, bool allowStartAtRealizedItem)
            {
                _factory = factory;
                _direction = direction;

                _factory.MapChanged += new MapChangedHandler(OnMapChanged);

                _factory.MoveToPosition(position, direction, allowStartAtRealizedItem, ref _cachedState);
                _done = (_factory.ItemsInternal.Count == 0);

                _factory.SetStatus(GeneratorStatus.GeneratingContainers);
            }
Example #29
0
        /// <summary> Begin generating at the given position and direction </summary>
        /// <remarks>
        /// This method must be called before calling GenerateNext.  It returns an
        /// IDisposable object that tracks the lifetime of the generation loop.
        /// This method sets the generator's status to GeneratingContent;  when
        /// the IDisposable is disposed, the status changes to ContentReady or
        /// Error, as appropriate.
        /// </remarks>
        IDisposable IItemContainerGenerator.StartAt(GeneratorPosition position, GeneratorDirection direction, bool allowStartAtRealizedItem)
        {
            if (_generator != null)
                throw new InvalidOperationException(SR.Get(SRID.GenerationInProgress));

            _generator = new Generator(this, position, direction, allowStartAtRealizedItem);
            return _generator;
        }
        /// <summary>
        /// Virtualize hidden items
        /// </summary>
        private void CleanUpItems()
        {
            try
            {
            UIElementCollection children = this.InternalChildren;
            IItemContainerGenerator generator = this.ItemContainerGenerator;

            for (int i = children.Count - 1; i >= 0; i--)
            {
                GeneratorPosition childGeneratorPos = new GeneratorPosition(i, 0);
                int itemIndex = generator.IndexFromGeneratorPosition(childGeneratorPos);

                if (itemIndex == -1)
                    continue;

                if (itemIndex < FirstVisibleIndex || itemIndex > LastVisibleIndex)
                {
                    generator.Remove(childGeneratorPos, 1);
                    RemoveInternalChildRange(i, 1);
                }
            }
        }
            catch (Exception ex)
            {
                VMuktiAPI.VMuktiHelper.ExceptionHandler(ex, "CleanUpItems()", "Controls\\VMuktiGrid\\Page\\VirtualizingTabPanel.cs");
            }
        }
Example #31
0
        //------------------------------------------------------
        //
        //  Private Methods
        //
        //------------------------------------------------------

        void MoveToPosition(GeneratorPosition position, GeneratorDirection direction, bool allowStartAtRealizedItem, ref GeneratorState state)
        {
            ItemBlock block = _itemMap;
            if (block == null)
                return;         // this can happen in event-leapfrogging situations (Dev11 283413)

            int itemIndex = 0;

            // first move to the indexed (realized) item
            if (position.Index != -1)
            {
                // find the right block
                int itemCount = 0;
                int index = position.Index;
                block = block.Next;
                while (index >= block.ContainerCount)
                {
                    itemCount += block.ItemCount;
                    index -= block.ContainerCount;
                    itemIndex += block.ItemCount;
                    block = block.Next;
                }

                // set the position
                state.Block = block;
                state.Offset = index;
                state.Count = itemCount;
                state.ItemIndex = itemIndex + index;
            }
            else
            {
                state.Block = block;
                state.Offset = 0;
                state.Count = 0;
                state.ItemIndex = itemIndex - 1;
            }

            // adjust the offset - we always set the state so it points to the next
            // item to be generated.
            int offset = position.Offset;
            if (offset == 0 && (!allowStartAtRealizedItem || state.Block == _itemMap))
            {
                offset = (direction == GeneratorDirection.Forward) ? 1 : -1;
            }

            // advance the state according to the offset
            if (offset > 0)
            {
                state.Block.MoveForward(ref state, true);
                -- offset;

                while (offset > 0)
                {
                    offset -= state.Block.MoveForward(ref state, allowStartAtRealizedItem, offset);
                }
            }
            else if (offset < 0)
            {
                if (state.Block == _itemMap)
                {
                    state.ItemIndex = state.Count = ItemsInternal.Count;
                }

                state.Block.MoveBackward(ref state, true);
                ++ offset;

                while (offset < 0)
                {
                    offset += state.Block.MoveBackward(ref state, allowStartAtRealizedItem, -offset);
                }
            }
        }
        private void CleanUpItems(int StartItemIndex, int itemsCount)
        {
            UIElementCollection children = InternalChildren;
            IItemContainerGenerator generator = ItemContainerGenerator;

            int first = StartItemIndex;
            int last = StartItemIndex + itemsCount - 1;
            for (int i = children.Count - 1; i >= 0; i--)
            {
                // Map a child index to an item index by going through a generator position
                GeneratorPosition childGeneratorPos = new GeneratorPosition(i, 0);
                int itemIndex = generator.IndexFromGeneratorPosition(childGeneratorPos);

                itemIndex = i + StartItemIndex;

            if (itemIndex < first || itemIndex > last)
                {
                    //generator.Remove(childGeneratorPos, 1);
                    //generator.Remove(new GeneratorPosition(itemIndex, 0), 1);

                    RemoveInternalChildRange(i, 1);
                }
            }
        }
Example #33
0
 /// <summary> Begin generating at the given position and direction </summary>
 /// <remarks>
 /// This method must be called before calling GenerateNext.  It returns an
 /// IDisposable object that tracks the lifetime of the generation loop.
 /// This method sets the generator's status to GeneratingContent;  when
 /// the IDisposable is disposed, the status changes to ContentReady or
 /// Error, as appropriate.
 /// </remarks>
 IDisposable IItemContainerGenerator.StartAt(GeneratorPosition position, GeneratorDirection direction)
 {
     return ((IItemContainerGenerator)this).StartAt(position, direction, false);
 }