示例#1
0
        private bool CheckEnoughSpaceForItemInRow(WrapRow row, RadVirtualizingDataControlItem item, bool addingAtStart)
        {
            switch (this.orientationCache)
            {
            case Orientation.Horizontal:
                if (addingAtStart)
                {
                    return(this.owner.availableWidth - (row.lastItem.horizontalOffsetCache + row.lastItem.width - row.firstItem.horizontalOffsetCache) >= item.width);
                }
                else
                {
                    return(row.firstItem.horizontalOffsetCache >= item.width);
                }

            case Orientation.Vertical:
                if (addingAtStart)
                {
                    return(this.owner.availableHeight - (row.lastItem.verticalOffsetCache + row.lastItem.height - row.firstItem.verticalOffsetCache) >= item.height);
                }
                else
                {
                    return(row.firstItem.verticalOffsetCache >= item.height);
                }
            }

            return(false);
        }
示例#2
0
        private SingleItemAnimationContext GetAnimationContextForTarget(RadVirtualizingDataControlItem target, bool lookInAdded)
        {
            if (lookInAdded)
            {
                foreach (SingleItemAnimationContext c in this.scheduledAddAnimations)
                {
                    if (c.AssociatedItem == target)
                    {
                        return(c);
                    }
                }
            }
            else
            {
                foreach (SingleItemAnimationContext c in this.scheduledRemoveAnimations)
                {
                    if (c.AssociatedItem == target)
                    {
                        return(c);
                    }
                }
            }

            return(null);
        }
示例#3
0
        internal override void ReorderViewportItemsOnItemRemoved(int removedAt, RadVirtualizingDataControlItem removedContainer)
        {
            double correctionLength = this.GetItemLength(removedContainer);

            if (this.reorderMode == CollectionChangeItemReorderMode.MoveItemsDown)
            {
                ////Apply the aggregated height correction to all affected visual items reamining on the viewport
                for (int i = removedAt; i < this.owner.realizedItems.Count; i++)
                {
                    RadVirtualizingDataControlItem itemToOffset = this.owner.realizedItems[i];
                    double currentVerticalOffset = itemToOffset.currentOffset;
                    this.SetItemOffset(itemToOffset, currentVerticalOffset - correctionLength);
                }
            }
            else
            {
                ////Apply the aggregated height correction to all affected visual items reamining on the viewport
                for (int i = 0; i < removedAt; i++)
                {
                    RadVirtualizingDataControlItem itemToOffset = this.owner.realizedItems[i];
                    double currentVerticalOffset = itemToOffset.currentOffset;
                    this.SetItemOffset(itemToOffset, currentVerticalOffset + correctionLength);
                }
            }
        }
示例#4
0
        internal override void OnOrientationChanged(Orientation newValue)
        {
            base.OnOrientationChanged(newValue);

            if (this.owner == null || !this.owner.IsTemplateApplied)
            {
                return;
            }

            if (this.owner.GetItemCount() > 0)
            {
                this.owner.StopAllAddedAnimations();
                this.owner.StopAllRemovedAnimations();

                while (this.owner.realizedItems.Count > 0)
                {
                    RadVirtualizingDataControlItem lastItem = this.owner.realizedItems[this.owner.realizedItems.Count - 1];
                    lastItem.SetVerticalOffset(0);
                    lastItem.SetHorizontalOffset(0);
                    this.owner.RecycleLastItem();
                }
                this.wrapRows.Clear();

                this.owner.BeginAsyncBalance();
                this.owner.BalanceVisualSpace();
            }
        }
示例#5
0
        internal override void ReorderViewportItemsOnItemReplaced(RadVirtualizingDataControlItem replacedItem)
        {
            if (this.reorderMode == CollectionChangeItemReorderMode.MoveItemsDown)
            {
                RadVirtualizingDataControlItem nextItem = replacedItem.next;
                while (nextItem != null)
                {
                    this.SetItemOffset(nextItem, nextItem.previous.currentOffset + this.GetItemLength(nextItem.previous));

                    nextItem = nextItem.next;
                }
            }
            else
            {
                RadVirtualizingDataControlItem processedItem = replacedItem;
                while (processedItem != null)
                {
                    if (processedItem.next != null)
                    {
                        this.SetItemOffset(processedItem, processedItem.next.currentOffset - this.GetItemLength(processedItem));
                    }

                    processedItem = processedItem.previous;
                }
            }
        }
示例#6
0
        internal override RadVirtualizingDataControlItem GetContainerForItem(IDataSourceItem item, int insertAt)
        {
            RadVirtualizingDataControlItem container = base.GetContainerForItem(item, insertAt);

            this.allItemsExtent += this.GetItemExtent(container);
            return(container);
        }
示例#7
0
        internal override void OnAfterItemRemovedAnimationEnded(SingleItemAnimationContext context)
        {
            double startingOffset = context.AssociatedItem.currentOffset;
            double offset         = context.RealizedLength;

            ////Apply the aggregated height correction to all affected visual items reamining on the viewport
            for (int i = 0; i < this.owner.realizedItems.Count; i++)
            {
                RadVirtualizingDataControlItem firstItem = this.owner.realizedItems[i];

                if (firstItem.currentOffset > startingOffset)
                {
                    if (firstItem.previous == null || (firstItem.previous != null && firstItem.previous.currentOffset + this.GetItemLength(firstItem.previous) <= firstItem.currentOffset - offset))
                    {
                        this.SetItemOffset(firstItem, firstItem.currentOffset - offset);
                    }
                    else
                    {
                        break;
                    }
                }
            }

            this.TranslateRemoveAnimatedItemsWithOffset(startingOffset, -offset);

            if (this.owner.IsLoaded)
            {
                this.ManageLowerViewport(false);
                this.CheckBottomScrollableBounds();
            }
        }
        /// <summary>
        /// Determines whether the specified data item is currently visible.
        /// </summary>
        /// <param name="dataItem"></param>
        /// <param name="includePartiallyVisibleItems">
        /// If this parameter is set to <c>true</c>, then the partially visible items will also be included.
        /// </param>
        public bool IsItemInViewport(object dataItem, bool includePartiallyVisibleItems = true)
        {
            if (!this.IsOperational())
            {
                return(false);
            }

            RadVirtualizingDataControlItem container = this.virtualizationStrategy.GetTopVisibleContainer();
            int    iterationStart     = container.associatedDataItem.Index - this.firstItemCache.associatedDataItem.Index;
            double bottomViewportEdge = this.virtualizationStrategy.ViewportLength;

            for (int i = iterationStart; i < this.realizedItems.Count; i++)
            {
                container = this.realizedItems[i];
                var itemTop = this.virtualizationStrategy.GetItemRelativeOffset(container);
                if (itemTop < bottomViewportEdge)
                {
                    if (!includePartiallyVisibleItems && (itemTop < 0 || itemTop + virtualizationStrategy.GetItemLength(container) > bottomViewportEdge))
                    {
                        continue;
                    }

                    if (dataItem.Equals(container.associatedDataItem.Value) && container.Visibility == Visibility.Visible)
                    {
                        return(true);
                    }
                }
                else
                {
                    break;
                }
            }

            return(false);
        }
示例#9
0
        private void SynchItemOffsetInRow(WrapRow row)
        {
            RadVirtualizingDataControlItem firstItem = row.firstItem;

            switch (this.orientationCache)
            {
            case Orientation.Horizontal:

                while (true)
                {
                    firstItem.SetVerticalOffset(row.rowOffset);
                    firstItem = firstItem.next;

                    if (firstItem.wrapRow != row)
                    {
                        break;
                    }
                }
                break;

            case Orientation.Vertical:
                while (true)
                {
                    firstItem.SetHorizontalOffset(row.rowOffset);
                    firstItem = firstItem.next;

                    if (firstItem.wrapRow != row)
                    {
                        break;
                    }
                }
                break;
            }
        }
        internal virtual RadVirtualizingDataControlItem GetContainerForItem(IDataSourceItem item, int insertAt)
        {
            RadVirtualizingDataControlItem cp = null;

            if (this.owner.recycledItems.Count == 0)
            {
                cp = this.owner.GenerateContainerForItem(item);
            }
            else
            {
                cp = this.owner.recycledItems.Dequeue();

                if ((this.owner.itemAddedAnimationCache != null && RadAnimationManager.IsAnimationScheduled(cp, this.owner.itemAddedAnimationCache)) ||
                    (this.owner.itemRemovedAnimationCache != null && RadAnimationManager.IsAnimationScheduled(cp, this.owner.itemRemovedAnimationCache)))
                {
                    this.owner.recycledItems.Enqueue(cp);
                    cp = this.owner.GenerateContainerForItem(item);
                }
                else
                {
                    this.owner.OnContainerStateChanged(cp, item, ItemState.Realizing);
                    this.owner.PrepareContainerForItemInternal(cp, item);
                    cp.Visibility = Visibility.Visible;
                }
            }

            this.MeasureContainer(cp);

            this.InsertIntoViewport(cp, insertAt);

            this.owner.firstItemCache = this.owner.realizedItems[0];
            this.owner.lastItemCache  = this.owner.realizedItems[this.owner.realizedItems.Count - 1];

            return(cp);
        }
示例#11
0
        internal override void ResetRealizationStartWhenLowerUIBufferRecycled(double position)
        {
            double bottomDifference = position - this.GetItemLength(this.owner.lastItemCache);

            if (bottomDifference > this.bottomVirtualizationThreshold)
            {
                int itemCount = (int)Math.Round(bottomDifference / this.averageItemLength, 0);

                RadVirtualizingDataControlItem firstRealizedDataItem = this.owner.FirstRealizedDataItem;
                int currentFirstItemIndex = 0;
                if (firstRealizedDataItem != null)
                {
                    currentFirstItemIndex = Math.Max(firstRealizedDataItem.associatedDataItem.Index - itemCount, 0);
                }

                IDataSourceItem newDataItem = firstRealizedDataItem.associatedDataItem;

                while (newDataItem.Index > currentFirstItemIndex)
                {
                    newDataItem = newDataItem.Previous;

                    Debug.Assert(newDataItem != null, "The currentLastItemIndex should be within the bounds of the flattened view of the collection.");
                }

                this.owner.ClearContainerForItemInternal(this.owner.lastItemCache, this.owner.lastItemCache.associatedDataItem);
                RadVirtualizingDataControlItem newRealized = this.GetContainerForItem(newDataItem, false);
                double currentTop = this.ScrollOffset;
                this.SetItemOffset(newRealized, currentTop - this.GetElementCanvasOffset(this.owner.itemsPanel));
            }
        }
示例#12
0
        internal override void ResetRealizationStartWhenUpperUIBufferRecycled(double position)
        {
            double topDifference = position + this.GetItemLength(this.owner.lastItemCache);

            if (topDifference < this.topVirtualizationThreshold)
            {
                int itemCount = (int)Math.Round(Math.Abs(topDifference) / this.averageItemLength, 0);

                RadVirtualizingDataControlItem lastRealizedDataItem = this.owner.LastRealizedDataItem;
                int currentLastItemIndex = this.owner.GetDataItemCount();

                if (lastRealizedDataItem != null)
                {
                    currentLastItemIndex = Math.Min(lastRealizedDataItem.associatedDataItem.Index + itemCount, currentLastItemIndex - 1);
                }

                IDataSourceItem newDataItem = lastRealizedDataItem.associatedDataItem;

                while (newDataItem.Index < currentLastItemIndex)
                {
                    newDataItem = newDataItem.Next;

                    Debug.Assert(newDataItem != null, "The currentLastItemIndex should be within the bounds of the flattened view of the collection.");
                }

                this.owner.ClearContainerForItemInternal(this.owner.lastItemCache, this.owner.lastItemCache.associatedDataItem);
                RadVirtualizingDataControlItem newRealized = this.GetContainerForItem(newDataItem, false);

                double currentBottom = this.ScrollOffset;
                this.SetItemOffset(newRealized, currentBottom - this.GetElementCanvasOffset(this.owner.itemsPanel));
            }
        }
示例#13
0
        internal override void OnContainerSizeChanged(RadVirtualizingDataControlItem container, Size newSize, Size oldSize)
        {
            WrapRow parentRow = container.wrapRow.firstItem == container ? container.wrapRow.previous != null ? container.wrapRow.previous : container.wrapRow : container.wrapRow;

            this.allItemsExtent += this.orientationCache == Orientation.Horizontal ? newSize.Width - oldSize.Width : newSize.Height - oldSize.Height;
            parentRow.rowLength  = 0;
            this.ReorderViewportItemsStartingAtRow(parentRow);
        }
示例#14
0
        internal override void ReorderViewportItemsOnItemReplaced(RadVirtualizingDataControlItem replacedItem)
        {
            WrapRow parentRow = replacedItem.wrapRow.firstItem == replacedItem ? replacedItem.wrapRow.previous != null ? replacedItem.wrapRow.previous : replacedItem.wrapRow : replacedItem.wrapRow;

            parentRow.rowLength = 0;

            this.ReorderViewportItemsStartingAtRow(parentRow);
        }
示例#15
0
        internal override RadVirtualizingDataControlItem GetContainerForItem(IDataSourceItem item, int insertAt)
        {
            RadVirtualizingDataControlItem container = base.GetContainerForItem(item, insertAt);

            this.realizedItemsLength += this.GetItemLength(container);

            return(container);
        }
        internal RadVirtualizingDataControlItem GenerateContainerForItem(IDataSourceItem item)
        {
            RadVirtualizingDataControlItem cp = this.GetContainerForItemOverride();

            this.OnContainerStateChanged(cp, item, ItemState.Realizing);
            this.itemsPanel.Children.Add(cp);
            this.PrepareContainerForItemOverride(cp, item);
            return(cp);
        }
        internal virtual double GetItemLength(RadVirtualizingDataControlItem item)
        {
            if (this.LayoutOrientation == Orientation.Horizontal)
            {
                return(item.width);
            }

            return(item.height);
        }
示例#18
0
        internal virtual double GetItemRowOffset(RadVirtualizingDataControlItem item)
        {
            if (this.orientationCache == Orientation.Vertical)
            {
                return(item.verticalOffsetCache);
            }

            return(item.horizontalOffsetCache);
        }
        internal void OnContainerSizeChanged(RadVirtualizingDataControlItem container, Size newSize, Size oldSize)
        {
            if (this.GetItemCount() == 0)
            {
                return;
            }

            this.virtualizationStrategy.OnContainerSizeChanged(container, newSize, oldSize);
        }
示例#20
0
        internal override bool PositionBottomRealizedItem(ref double visibleItemsBottom)
        {
            RadVirtualizingDataControlItem lastRealizedItem = this.owner.lastItemCache;
            double offset = lastRealizedItem.previous != null ? lastRealizedItem.previous.currentOffset + this.GetItemLength(lastRealizedItem.previous) : 0;

            this.SetItemOffset(lastRealizedItem, offset);
            visibleItemsBottom += this.GetItemLength(lastRealizedItem);

            return(true);
        }
示例#21
0
        internal override bool PositionTopRealizedItem(ref double visibleItemsTop)
        {
            RadVirtualizingDataControlItem firstRealizedItem = this.owner.firstItemCache;
            double verticalOffset = firstRealizedItem.next != null ? firstRealizedItem.next.currentOffset - this.GetItemLength(firstRealizedItem) : 0;

            this.SetItemOffset(firstRealizedItem, verticalOffset);
            visibleItemsTop -= this.GetItemLength(firstRealizedItem);

            return(true);
        }
        internal virtual void PlaySingleItemRemovedAnimation(RadVirtualizingDataControlItem item)
        {
            int realizedIndex = item.associatedDataItem.Index - this.owner.firstItemCache.associatedDataItem.Index;

            RadAnimationManager.Play(item, this.owner.itemRemovedAnimationCache);
            this.owner.scheduledRemoveAnimations.Add(new SingleItemAnimationContext()
            {
                AssociatedItem = item, RealizedLength = this.GetItemLength(item), RealizedIndex = realizedIndex
            });
        }
示例#23
0
        internal override void ReorderViewportItemsOnItemAddedOnTop(IDataSourceItem addedItem)
        {
            RadVirtualizingDataControlItem firstRealized = this.owner.firstItemCache;
            IDataSourceItem prev = this.owner.GetItemBefore(firstRealized.associatedDataItem);
            RadVirtualizingDataControlItem newFirst = this.GetContainerForItem(prev, false);

            newFirst.wrapRow           = firstRealized.wrapRow;
            newFirst.wrapRow.firstItem = newFirst;
            this.ReorderViewportItemsStartingAtRow(newFirst.wrapRow);
        }
 internal virtual void InvalidateItemOffset(RadVirtualizingDataControlItem item)
 {
     if (this.LayoutOrientation == Orientation.Vertical)
     {
         item.InvalidateVerticalOffset();
     }
     else
     {
         item.InvalidateHorizontalOffset();
     }
 }
示例#25
0
 private void TranslateRemoveAnimatedItemsWithOffset(double startingFrom, double offset)
 {
     foreach (SingleItemAnimationContext item in this.owner.scheduledRemoveAnimations)
     {
         RadVirtualizingDataControlItem associatedItem = item.AssociatedItem;
         if (associatedItem.currentOffset > startingFrom)
         {
             this.SetItemOffset(associatedItem, associatedItem.currentOffset + offset);
         }
     }
 }
 internal virtual void SetItemOffset(RadVirtualizingDataControlItem item, double offset)
 {
     if (this.LayoutOrientation == Orientation.Vertical)
     {
         item.SetVerticalOffset(offset);
     }
     else
     {
         item.SetHorizontalOffset(offset);
     }
 }
        /// <summary>Prepares the specified element to display the specified item. </summary>
        /// <param name="element">The element used to display the specified item.</param>
        /// <param name="item">The item to display.</param>
        protected virtual void PrepareContainerForItemOverride(RadVirtualizingDataControlItem element, IDataSourceItem item)
        {
            element.BindToDataItem(item);

            this.PrepareStyle(element, item);

            if (item.Value != RadListSource.UnsetObject)
            {
                this.PrepareDataItem(element, item);
            }
        }
        internal virtual void ManageUpperViewport(bool recycle)
        {
            if (this.owner.firstItemCache == null)
            {
                return;
            }

            if (recycle)
            {
                double visibleItemsBottom = this.GetRealizedItemsBottom();
                while (this.CanRecycleBottom(visibleItemsBottom))
                {
                    this.RecycleBottom(ref visibleItemsBottom);
                }

                if (this.owner.lastItemCache != null &&
                    this.owner.firstItemCache == this.owner.lastItemCache &&
                    !(this.owner.IsFirstItemFirstInListSource() || this.owner.IsLastItemLastInListSource()))
                {
                    this.ResetRealizationStartWhenLowerUIBufferRecycled(visibleItemsBottom);
                }
            }

            bool processed = false;

            double visibleItemsTop = this.GetRealizedItemsTop();

            while (this.CanRealizeTop(visibleItemsTop))
            {
                IDataSourceItem item = this.owner.GetItemBefore(this.owner.firstItemCache.associatedDataItem);
                if (item == null)
                {
                    break;
                }

                if (processed && this.owner.useAsyncBalance)
                {
                    this.owner.ScheduleAsyncBalance();
                    return;
                }

                RadVirtualizingDataControlItem uiItem = this.GetContainerForItem(item, false);
                bool itemPositioned = this.PositionTopRealizedItem(ref visibleItemsTop);
                if (itemPositioned)
                {
                    this.owner.OnContainerStateChanged(uiItem, item, ItemState.Realized);
                    processed = true;
                }
                else
                {
                    this.owner.RecycleFirstItem();
                }
            }
        }
示例#29
0
        internal override double GetItemRelativeOffset(RadVirtualizingDataControlItem item)
        {
            switch (this.orientationCache)
            {
            case Orientation.Horizontal:
                return(item.verticalOffsetCache + Canvas.GetTop(this.owner.itemsPanel) - this.owner.manipulationContainer.VerticalOffset);

            case Orientation.Vertical:
                return(item.horizontalOffsetCache + Canvas.GetLeft(this.owner.itemsPanel) - this.owner.manipulationContainer.HorizontalOffset);
            }

            return(0);
        }
示例#30
0
        internal override RadVirtualizingDataControlItem GetTopVisibleContainer()
        {
            ////The approach here is to calculate the possible
            ////index of the topmost item by considering the upper buffer size
            ////and the average item height. In the ideal case of having equal height
            ////containers, the index will be calculated exactly. In case of wrong index calculation
            ////we estimate the direction we have to take in order to find the topmost item and
            ////interate to it.
            if (this.owner.realizedItems.Count == 0)
            {
                return(null);
            }

            if (this.averageItemLength == 0)
            {
                return(this.owner.firstItemCache);
            }

            double topThresholdAbs = Math.Abs(Math.Max(this.GetItemRelativeOffset(this.owner.firstItemCache), this.topVirtualizationThreshold));
            int    countOfTopItems = Math.Min((int)(topThresholdAbs / this.averageItemLength), this.owner.realizedItems.Count - 1);
            RadVirtualizingDataControlItem topElement = this.owner.realizedItems[countOfTopItems];
            int deltaFactor        = Math.Round(this.GetItemRelativeOffset(topElement), 1) > 0 ? -1 : 1;
            int realizedItemsCount = this.owner.realizedItems.Count;

            for (int i = countOfTopItems; i > -1 && i < realizedItemsCount; i += deltaFactor)
            {
                topElement = this.owner.realizedItems[i];

                if (deltaFactor < 0)
                {
                    if (Math.Round(this.GetItemRelativeOffset(topElement), 1) <= 0)
                    {
                        return(topElement);
                    }
                }
                else
                {
                    if (Math.Round(this.GetItemRelativeOffset(topElement), 1) == 0)
                    {
                        return(topElement);
                    }

                    if (Math.Round(this.GetItemRelativeOffset(topElement), 1) > 0)
                    {
                        return(topElement.previous != null ? topElement.previous : topElement);
                    }
                }
            }

            return(topElement);
        }