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); } }
public void SetRenderInfo(IDataSourceItem item, ItemLayoutInfo info) { if (info != ItemLayoutInfo.Invalid) { this.itemSlotsRepository[item] = info; } }
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); }
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); } }
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); } }
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); } }
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); }