internal override RadVirtualizingDataControlItem GetContainerForItem(IDataSourceItem item, int insertAt)
        {
            RadVirtualizingDataControlItem container = base.GetContainerForItem(item, insertAt);

            this.allItemsExtent += this.GetItemExtent(container);
            return(container);
        }
Exemple #2
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();
            }
        }
Exemple #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);
                }
            }
        }
Exemple #4
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;
                }
            }
        }
        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 override void ResetRealizationStartWhenLowerUIBufferRecycled(double position)
        {
            double bottomDifference = position - this.GetItemLength(this.owner.lastItemCache);

            if (bottomDifference > this.bottomVirtualizationThreshold + this.ScrollOffset)
            {
                int rowCount  = (int)Math.Round(bottomDifference / this.averageItemLength, 0);
                int itemCount = rowCount * this.stackCount;
                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.");
                }

                while (this.owner.realizedItems.Count > 0)
                {
                    this.RecycleItem(this.owner.realizedItems[0]);
                }

                var    newRealized = this.GetContainerForItem(newDataItem, false);
                double currentTop  = this.ScrollOffset;
                this.PositionBottomRealizedItem(this.owner.lastItemCache, ref currentTop);
            }
        }
Exemple #7
0
        internal override void ReorderViewportItemsOnItemReplaced(RadVirtualizingDataControlItem replacedItem)
        {
            RadVirtualizingDataControlItem pivotContainer = replacedItem.next;

            int containersToSkip = 0;


            //TODO: rearange items.

            if (pivotContainer != null)
            {
                containersToSkip = Math.Max(this.stackCount - this.owner.realizedItems.IndexOf(pivotContainer), 0);
            }

            while (pivotContainer != null)
            {
                if (containersToSkip > 0)
                {
                    containersToSkip--;
                    continue;
                }
                this.slotsRepository.Remove(pivotContainer.associatedDataItem.Index);
                pivotContainer = pivotContainer.next;
            }

            this.ReorderViewportOnItemsChanged();
        }
        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);
        }
Exemple #9
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.owner.BeginAsyncBalance();
                this.owner.BalanceVisualSpace();
            }
        }
Exemple #10
0
        /// <summary>
        /// Determines whether the specified data item is currently visible.
        /// </summary>
        /// <param name="dataItem">The data item.</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 + this.virtualizationStrategy.ScrollOffset;

            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 < this.virtualizationStrategy.ScrollOffset || itemTop + this.virtualizationStrategy.GetItemLength(container) > bottomViewportEdge))
                    {
                        continue;
                    }

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

            return(false);
        }
        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);
        }
        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);
        }
Exemple #13
0
        internal override RadVirtualizingDataControlItem GetContainerForItem(IDataSourceItem item, int insertAt)
        {
            RadVirtualizingDataControlItem container = base.GetContainerForItem(item, insertAt);

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

            return(container);
        }
        internal virtual double GetItemRowOffset(RadVirtualizingDataControlItem item)
        {
            if (this.orientationCache == Orientation.Vertical)
            {
                return(item.verticalOffsetCache);
            }

            return(item.horizontalOffsetCache);
        }
Exemple #15
0
        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);
        }
        internal void OnContainerSizeChanged(RadVirtualizingDataControlItem container, Size newSize, Size oldSize)
        {
            if (this.GetItemCount() == 0)
            {
                return;
            }

            this.virtualizationStrategy.OnContainerSizeChanged(container, newSize, oldSize);
        }
Exemple #18
0
        internal override bool PositionBottomRealizedItem(RadVirtualizingDataControlItem item, ref double visibleItemsBottom)
        {
            RadVirtualizingDataControlItem realizedItem = item;
            double offset = realizedItem.previous != null ? realizedItem.previous.CurrentOffset + this.GetItemLength(realizedItem.previous) : this.ScrollOffset;

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

            return(true);
        }
        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 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
            });
        }
        internal virtual void RefreshViewportOnItemRemoved(int startIndex, IDataSourceItem removedItem)
        {
            if (this.generatedItemsLength.ContainsKey(removedItem.Index))
            {
                this.generatedItemsLength.Remove(removedItem.Index);
            }

            int firstRealizedIndex = this.owner.GetFirstItemCacheIndex();
            int lastRealizedIndex  = this.owner.GetLastItemCacheIndex();
            int?listStartIndex     = null;

            ////Check whether the change has occured among the currently realized items.
            if (startIndex >= firstRealizedIndex && startIndex <= lastRealizedIndex)
            {
                listStartIndex = startIndex;
            }
            ////If the change has occured among the realized items, update the screen
            if (listStartIndex.HasValue)
            {
                int iterationStartIndex = this.owner.GetItemRealizedIndexFromListSourceIndex(listStartIndex.Value, firstRealizedIndex);

                RadVirtualizingDataControlItem itemToRecycle = this.owner.realizedItems[iterationStartIndex];
                if (this.owner.itemRemovedAnimationCache != null && (this.owner.itemAnimationModeCache & ItemAnimationMode.PlayOnRemove) != 0 && this.owner.CanPlayAnimationForItem(itemToRecycle, false))
                {
                    // If we have item remove animation defined, we recycle the item without hiding it and start the remove animation.
                    this.owner.itemRemovedAnimationCache.ApplyInitialValues(itemToRecycle);
                    this.owner.PlaySingleItemRemovedAnimation(itemToRecycle);
                    this.RecycleItem(itemToRecycle, false);
                }
                else
                {
                    ////Recycle the visual item associated with the removed data item
                    this.owner.ClearContainerForItemInternal(itemToRecycle, itemToRecycle.associatedDataItem);
                    this.ReorderViewportItemsOnItemRemoved(iterationStartIndex, itemToRecycle);
                }
            }
            else if (startIndex < firstRealizedIndex)
            {
                this.ReorderViewportItemsOnItemRemovedFromTop(removedItem);
            }

            ////If there are no more items reset the scroll offset
            if (this.owner.GetItemCount() == 0)
            {
                this.ScrollToOffset(0, null);
                return;
            }

            ////Balance the visual space
            if (this.owner.scheduledRemoveAnimations.Count == 0)
            {
                this.owner.BalanceVisualSpace();
            }
        }
 internal virtual void SetItemOffset(RadVirtualizingDataControlItem item, double offset)
 {
     if (this.LayoutOrientation == Orientation.Vertical)
     {
         item.SetVerticalOffset(offset);
     }
     else
     {
         item.SetHorizontalOffset(offset);
     }
 }
 internal virtual void InvalidateItemOffset(RadVirtualizingDataControlItem item)
 {
     if (this.LayoutOrientation == Orientation.Vertical)
     {
         item.InvalidateVerticalOffset();
     }
     else
     {
         item.InvalidateHorizontalOffset();
     }
 }
Exemple #24
0
        /// <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);
            }
        }
Exemple #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 RecycleItem(RadVirtualizingDataControlItem item, bool setVisibility)
        {
            if (item.scheduledForBatchAnimation)
            {
                if (this.owner.itemAddedAnimationCache != null)
                {
                    this.owner.itemAddedAnimationCache.ClearAnimation(item);
                }
            }
            item.scheduledForBatchAnimation = false;
            IDataSourceItem associatedItem = item.associatedDataItem;

            this.owner.OnContainerStateChanged(item, associatedItem, ItemState.Recycling);

            item.ResetDataItemBinding();
            if (setVisibility)
            {
                item.Visibility = Visibility.Collapsed;
                //   item.SetHorizontalOffset(0);
                //  item.SetVerticalOffset(0);
            }
            this.owner.realizedItems.Remove(item);
            this.owner.recycledItems.Enqueue(item);

            if (item.next != null)
            {
                item.next.previous = item.previous;
            }

            if (item.previous != null)
            {
                item.previous.next = item.next;
            }

            item.next     = null;
            item.previous = null;

            int realizedItemsCount = this.owner.realizedItems.Count;

            if (this.owner.realizedItems.Count > 0)
            {
                this.owner.lastItemCache  = this.owner.realizedItems[realizedItemsCount - 1];
                this.owner.firstItemCache = this.owner.realizedItems[0];
            }
            else
            {
                this.averageItemLength    = 0;
                this.owner.lastItemCache  = null;
                this.owner.firstItemCache = null;
            }

            this.owner.OnContainerStateChanged(item, associatedItem, ItemState.Recycled);
        }
Exemple #27
0
        internal override double GetItemRelativeOffset(RadVirtualizingDataControlItem item)
        {
            switch (this.orientationCache)
            {
            case Orientation.Horizontal:
                return(item.verticalOffsetCache);

            case Orientation.Vertical:
                return(item.horizontalOffsetCache);
            }

            return(0);
        }
Exemple #28
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);
        }
Exemple #29
0
        internal void OnContainerStateChanged(RadVirtualizingDataControlItem container, IDataSourceItem item, ItemState state)
        {
            container.UpdateItemState(state);

            if (state == ItemState.Realized)
            {
                container.Attach(this);
            }
            else if (state == ItemState.Recycled)
            {
                container.Detach();
            }

            this.OnItemStateChanged(item.Value, state);
        }
Exemple #30
0
        internal override void ReorderViewportItemsOnItemRemoved(int removedAt, RadVirtualizingDataControlItem removedContainer)
        {
            if (removedAt < this.owner.realizedItems.Count)
            {
                IDataSourceItem firstRealized = this.owner.realizedItems[removedAt].associatedDataItem;

                while (firstRealized != null)
                {
                    this.slotsRepository.Remove(firstRealized.GetHashCode());
                    firstRealized = firstRealized.Next;
                }

                this.ReorderViewportOnItemsChanged();
            }
        }