예제 #1
0
        private void RecycleItems(ItemLayoutInfo layoutInfo)
        {
            foreach (UIElement child in Children)
            {
                var virtualItemIndex = GetVirtualItemIndex(child);

                if (virtualItemIndex < layoutInfo.FirstRealizedItemIndex || virtualItemIndex > layoutInfo.LastRealizedItemIndex)
                {
                    var generatorPosition = _itemsGenerator.GeneratorPositionFromIndex(virtualItemIndex);
                    if (generatorPosition.Index >= 0)
                    {
                        try
                        {
                            _itemsGenerator.Recycle(generatorPosition, 1);
                        }
                        catch (ArgumentException)
                        {
                            //I have seen the following exception which appears to be a non-issue
                            // GeneratorPosition '0,10' passed to Remove does not have Offset equal to 0.
                        }
                    }
                }
                SetVirtualItemIndex(child, -1);
            }
        }
예제 #2
0
 public void SetRenderInfo(IDataSourceItem item, ItemLayoutInfo info)
 {
     if (info != ItemLayoutInfo.Invalid)
     {
         this.itemSlotsRepository[item] = info;
     }
 }
예제 #3
0
        public ItemLayoutInfo GetFreeSpot(IDataSourceItem item, bool forward)
        {
            if (forward && item.Previous == null || !forward && item.Next == null)
            {
                return(new ItemLayoutInfo());
            }


            //TODO Implement for backwards
            double[] columnsLength = forward ? new double[this.columnCount] : Enumerable.Repeat(double.MaxValue, this.columnCount).ToArray();

            var            pivotItem = forward ? item.Previous : item.Next;
            ItemLayoutInfo itemInfo;

            List <int> foundColumns = new List <int>();

            while (foundColumns.Count < this.columnCount)
            {
                if (pivotItem != null)
                {
                    itemInfo = this.GetRenderInfo(pivotItem);

                    if (itemInfo != ItemLayoutInfo.Invalid && !foundColumns.Contains(itemInfo.ColumnIndex))
                    {
                        //Implement backward
                        foundColumns.Add(itemInfo.ColumnIndex);
                        columnsLength[itemInfo.ColumnIndex] = itemInfo.Position + itemInfo.Length;
                    }

                    pivotItem = forward ? item.Previous : item.Next;
                }
            }

            var            min    = columnsLength.Min();
            ItemLayoutInfo result = ItemLayoutInfo.Invalid;

            for (int i = 0; i < columnsLength.Length; i++)
            {
                if (columnsLength[i] == min)
                {
                    result = new ItemLayoutInfo(columnsLength[i], 0, i);
                }
            }

            return(result);
        }
예제 #4
0
        private void RecycleItems(ItemLayoutInfo layoutInfo)
        {
            foreach (UIElement child in Children)
            {
                var virtualItemIndex = GetVirtualItemIndex(child);

                if (virtualItemIndex < layoutInfo.FirstRealizedItemIndex || virtualItemIndex > layoutInfo.LastRealizedItemIndex)
                {
                    var generatorPosition = _itemsGenerator.GeneratorPositionFromIndex(virtualItemIndex);
                    if (generatorPosition.Index >= 0)
                    {
                        _itemsGenerator.Recycle(generatorPosition, 1);
                    }
                }
                SetVirtualItemIndex(child, -1);
            }
        }
예제 #5
0
        private void RecycleItems(ItemLayoutInfo layoutInfo)
        {
            foreach (UIElement child in Children)
            {
                var virtualItemIndex = GetVirtualItemIndex(child);

                var cacheLength = GetCacheLength(this);
                var cacheUnit   = GetCacheLengthUnit(this);

                double multipler;
                switch (cacheUnit)
                {
                case VirtualizationCacheLengthUnit.Pixel:
                    multipler = Orientation == Orientation.Vertical ? 1d / _itemWidth : 1d / _itemHeight;
                    break;

                case VirtualizationCacheLengthUnit.Item:
                    multipler = 1d;
                    break;

                case VirtualizationCacheLengthUnit.Page:
                    multipler = layoutInfo.LastRealizedItemIndex - layoutInfo.FirstRealizedItemIndex + 1;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                if (virtualItemIndex < layoutInfo.FirstRealizedItemIndex - cacheLength.CacheBeforeViewport * multipler ||
                    virtualItemIndex > layoutInfo.LastRealizedItemIndex + cacheLength.CacheAfterViewport * multipler)
                {
                    var generatorPosition = _itemsGenerator.GeneratorPositionFromIndex(virtualItemIndex);
                    if (generatorPosition.Index >= 0)
                    {
                        _itemsGenerator.Recycle(generatorPosition, 1);
                    }
                }

                SetVirtualItemIndex(child, -1);
            }
        }
예제 #6
0
        private void RecycleItems(ItemLayoutInfo layoutInfo)
        {
            foreach (UIElement child in Children)
            {
                int virtualItemIndex = GetVirtualItemIndex(child);

                if (virtualItemIndex < layoutInfo.FirstRealizedItemIndex ||
                    virtualItemIndex > layoutInfo.LastRealizedItemIndex)
                {
                    GeneratorPosition generatorPosition = _itemsGenerator.GeneratorPositionFromIndex(virtualItemIndex);
                    if (generatorPosition.Index >= 0)
                    {
                        _itemsGenerator.Recycle(generatorPosition, 1);
                    }
                }

                SetVirtualItemIndex(child, RecycledIndex);
            }
        }
예제 #7
0
        private void RecycleItems(ItemLayoutInfo layoutInfo) {
            foreach (UIElement child in Children) {
                var virtualItemIndex = GetVirtualItemIndex(child);

                var cacheLength = GetCacheLength(this);
                var cacheUnit = GetCacheLengthUnit(this);

                double multipler;
                switch (cacheUnit) {
                    case VirtualizationCacheLengthUnit.Pixel:
                        multipler = Orientation == Orientation.Vertical ? 1d / _itemWidth : 1d / _itemHeight;
                        break;
                    case VirtualizationCacheLengthUnit.Item:
                        multipler = 1d;
                        break;
                    case VirtualizationCacheLengthUnit.Page:
                        multipler = layoutInfo.LastRealizedItemIndex - layoutInfo.FirstRealizedItemIndex + 1;
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }

                if (virtualItemIndex < layoutInfo.FirstRealizedItemIndex - cacheLength.CacheBeforeViewport * multipler
                        || virtualItemIndex > layoutInfo.LastRealizedItemIndex + cacheLength.CacheAfterViewport * multipler) {
                    var generatorPosition = _itemsGenerator.GeneratorPositionFromIndex(virtualItemIndex);
                    if (generatorPosition.Index >= 0) {
                        _itemsGenerator.Recycle(generatorPosition, 1);
                    }
                }

                SetVirtualItemIndex(child, -1);
            }
        }
예제 #8
0
        private void RecycleItems(ItemLayoutInfo layoutInfo)
        {
            foreach (UIElement child in Children)
            {
                var virtualItemIndex = GetVirtualItemIndex(child);

                if (virtualItemIndex < layoutInfo.FirstRealizedItemIndex || virtualItemIndex > layoutInfo.LastRealizedItemIndex)
                {
                    var generatorPosition = _itemsGenerator.GeneratorPositionFromIndex(virtualItemIndex);
                    if (generatorPosition.Index >= 0)
                    {
                        try
                        {
                            _itemsGenerator.Recycle(generatorPosition, 1);
                        }
                        catch (ArgumentException)
                        {
                            //I have seen the following exception which appears to be a non-issue
                            // GeneratorPosition '0,10' passed to Remove does not have Offset equal to 0.
                        }

                    }
                }
                SetVirtualItemIndex(child, -1);
            }
        }
예제 #9
0
        protected override Size MeasureOverride(Size availableSize)
        {
            _isInMeasure = true;
            if (_itemsControl != null)
            {
                _childLayouts.Clear();

                ExtentInfo extentInfo = GetExtentInfo(availableSize, ItemHeight);

                EnsureScrollOffsetIsWithinConstrains(extentInfo);

                ItemLayoutInfo layoutInfo = GetLayoutInfo(availableSize, ItemHeight, extentInfo);

                RecycleItems(layoutInfo);

                // Determine where the first item is in relation to previously realized items
                GeneratorPosition generatorStartPosition =
                    _itemsGenerator.GeneratorPositionFromIndex(layoutInfo.FirstRealizedItemIndex);

                int visualIndex = 0;

                double currentX          = layoutInfo.FirstRealizedItemLeft;
                double currentY          = layoutInfo.FirstRealizedLineTop;
                var    availableItemSize = new Size(ItemWidth, ItemHeight);

                using (_itemsGenerator.StartAt(generatorStartPosition, GeneratorDirection.Forward, true))
                {
                    for (int itemIndex = layoutInfo.FirstRealizedItemIndex;
                         itemIndex <= layoutInfo.LastRealizedItemIndex;
                         itemIndex++, visualIndex++)
                    {
                        bool newlyRealized;

                        var child = (UIElement)_itemsGenerator.GenerateNext(out newlyRealized);
                        SetVirtualItemIndex(child, itemIndex);

                        if (newlyRealized)
                        {
                            InsertInternalChild(visualIndex, child);
                        }
                        else
                        {
                            // check if item needs to be moved into a new position in the Children collection
                            if (visualIndex < Children.Count)
                            {
                                if (Children[visualIndex] != child)
                                {
                                    int childCurrentIndex = Children.IndexOf(child);

                                    if (childCurrentIndex >= 0)
                                    {
                                        RemoveInternalChildRange(childCurrentIndex, 1);
                                    }

                                    InsertInternalChild(visualIndex, child);
                                }
                            }
                            else
                            {
                                // we know that the child can't already be in the children collection
                                // because we've been inserting children in correct visualIndex order,
                                // and this child has a visualIndex greater than the Children.Count
                                AddInternalChild(child);
                            }
                        }

                        // only prepare the item once it has been added to the visual tree
                        _itemsGenerator.PrepareItemContainer(child);

                        child.Measure(availableItemSize);

                        _childLayouts.Add(child, new Rect(currentX, currentY, ItemWidth, ItemHeight));

                        if (currentX + ItemWidth * 2 >= availableSize.Width)
                        {
                            // wrap to a new line
                            currentY += ItemHeight;
                            currentX  = 0;
                        }
                        else
                        {
                            currentX += ItemWidth;
                        }
                    }
                }

                RemoveRedundantChildren();
                UpdateScrollInfo(availableSize, extentInfo);
            }
            Size desiredSize = GetPanelDesiredSize(availableSize);

            _isInMeasure = false;
            return(desiredSize);
        }