Beispiel #1
0
        private void AddItemsToPresenter(GeneratorPosition position, int count)
        {
            if (this.itemsPresenter == null ||
                this.itemsPresenter.Child == null ||
                this.itemsPresenter.Child is VirtualizingPanel)
            {
                return;
            }

            Panel panel = this.itemsPresenter.Child;
            int newIndex = this.ItemContainerGenerator.IndexFromGeneratorPosition(position);

            using (IDisposable p = ItemContainerGenerator.StartAt(position, GeneratorDirection.Forward, true))
            {
                for (int i = 0; i < count; i++)
                {
                    object item = this.Items[newIndex + i];
                    DependencyObject container = null;

                    bool fresh;
                    container = this.ItemContainerGenerator.GenerateNext(out fresh);

                    FrameworkElement f = container as FrameworkElement;

                    if (f != null && !(item is FrameworkElement))
                    {
                        f.DataContext = item;
                    }

                    panel.InternalChildren.Insert(newIndex + i, (UIElement)container);
                    this.ItemContainerGenerator.PrepareItemContainer(container);
                }
            }
        }
Beispiel #2
0
        private void RemoveItemsFromPresenter(GeneratorPosition position, int count)
        {
            if (this.itemsPresenter == null ||
                this.itemsPresenter.Child == null ||
                this.itemsPresenter.Child is VirtualizingPanel)
            {
                return;
            }

            Panel panel = this.itemsPresenter.Child;

            while (count-- > 0)
            {
                panel.InternalChildren.RemoveAt(position.Index);
            }
        }
        internal void Recycle(GeneratorPosition position, int count)
        {
            this.CheckOffsetAndRealized(position, count);

            int index = this.IndexFromGeneratorPosition(position);
            
            for (int i = 0; i < count; i++)
            {
                this.Cache.Enqueue(this.ContainerIndexMap[index + i]);
            }

            this.Remove(position, count);
        }
        private void CheckOffsetAndRealized(GeneratorPosition position, int count)
        {
            if (position.Offset != 0)
            {
                throw new ArgumentException("position.Offset must be zero as the position must refer to a realized element.");
            }

            int index = this.IndexFromGeneratorPosition(position);
            int rangeIndex = this.RealizedElements.FindRangeIndexForValue(index);
            RangeCollection.Range range = this.RealizedElements.Ranges[rangeIndex];

            if (index < range.Start || (index + count) > range.Start + range.Count)
            {
                throw new InvalidOperationException("Only items which have been Realized can be removed.");
            }
        }
        internal void Remove(GeneratorPosition position, int count)
        {
            this.CheckOffsetAndRealized(position, count);

            int index = this.IndexFromGeneratorPosition(position);
            for (int i = 0; i < count; i++)
            {
                var container = this.ContainerIndexMap[index + i];
                var item = this.ContainerItemMap[container];
                this.ContainerIndexMap.Remove(container, index + i);
                this.ContainerItemMap.Remove(container);
                this.RealizedElements.Remove(index + i);
                this.Owner.ClearContainerForItem(container, item);
            }
        }
        internal IDisposable StartAt(
            GeneratorPosition position,
            GeneratorDirection direction,
            bool allowStartAtRealizedItem)
        {
            if (GenerationState != null)
            {
                throw new InvalidOperationException("Cannot call StartAt while a generation operation is in progress");
            }

            GenerationState = new GenerationState
            {
                AllowStartAtRealizedItem = allowStartAtRealizedItem,
                Direction = direction,
                Position = position,
                Generator = this
            };

            return GenerationState;
        }
        internal void OnOwnerItemsItemsChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            int itemCount;
            int itemUICount;
            GeneratorPosition oldPosition = new GeneratorPosition(-1, 0);
            GeneratorPosition position;

            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    if ((e.NewStartingIndex + 1) != this.Owner.Items.Count)
                    {
                        this.MoveExistingItems(e.NewStartingIndex, 1);
                    }

                    itemCount = 1;
                    itemUICount = 0;
                    position = this.GeneratorPositionFromIndex(e.NewStartingIndex);
                    break;

                case NotifyCollectionChangedAction.Remove:
                    itemCount = 1;
                    itemUICount = this.RealizedElements.Contains(e.OldStartingIndex) ? 1 : 0;
                    position = this.GeneratorPositionFromIndex(e.OldStartingIndex);
                    
                    if (itemUICount == 1)
                    {
                        this.Remove(position, 1);
                    }

                    this.MoveExistingItems(e.OldStartingIndex, -1);
                    break;

                case NotifyCollectionChangedAction.Replace:
                    if (!this.RealizedElements.Contains(e.NewStartingIndex))
                    {
                        return;
                    }

                    itemCount = 1;
                    itemUICount = 1;
                    position = this.GeneratorPositionFromIndex(e.NewStartingIndex);
                    
                    this.Remove(position, 1);

                    bool fresh;
                    var newPos = this.GeneratorPositionFromIndex(e.NewStartingIndex);
                    using (this.StartAt(newPos, GeneratorDirection.Forward, true))
                    {
                        this.PrepareItemContainer(this.GenerateNext(out fresh));
                    }

                    break;

                case NotifyCollectionChangedAction.Reset:
                    itemCount = e.OldItems == null ? 0 : e.OldItems.Count;
                    itemUICount = this.RealizedElements.Count;
                    position = new GeneratorPosition(-1, 0);
                    this.RemoveAll();
                    break;

                default:
                    Console.WriteLine("*** Critical error in ItemContainerGenerator.OnOwnerItemsItemsChanged. NotifyCollectionChangedAction.{0} is not supported", e.Action);
                    return;
            }

            ItemsChangedEventArgs args = new ItemsChangedEventArgs
            {
                Action = e.Action,
                ItemCount = itemCount,
                ItemUICount = itemUICount,
                OldPosition = oldPosition,
                Position = position
            };

            var h = this.ItemsChanged;

            if (h != null)
            {
                h(this, args);
            }
        }
 void IRecyclingItemContainerGenerator.Recycle(GeneratorPosition position, int count)
 {
     this.Recycle(position, count);
 }
 IDisposable IItemContainerGenerator.StartAt(
     GeneratorPosition position,
     GeneratorDirection direction,
     bool allowStartAtRealizedItem)
 {
     return this.StartAt(position, direction, allowStartAtRealizedItem);
 }
 void IItemContainerGenerator.Remove(GeneratorPosition position, int count)
 {
     this.Remove(position, count);
 }
        public int IndexFromGeneratorPosition(GeneratorPosition position)
        {
            // We either have everything realised or nothing realised, so we can
            // simply just add Index and Offset together to get the right index (i think)
            if (position.Index == -1)
            {
                if (position.Offset < 0)
                {
                    return this.Owner.Items.Count + position.Offset;
                }
                else
                {
                    return position.Offset - 1;
                }
            }
            else
            {
                if (position.Index > this.Owner.Items.Count)
                {
                    return -1;
                }

                if (position.Index >= 0 && position.Index < this.RealizedElements.Count)
                {
                    return this.RealizedElements[position.Index] + position.Offset;
                }

                return position.Index + position.Offset;
            }
        }