/// <summary> /// Initializes virtualization if all of the prerequisites are available, so it's safe to call once each is set. /// </summary> private void InitializeVirtualizationIfReady() { if ((_mediaStrip == null) || (_size == null)) { // We don't have everything we need to initialize, wait for the next call return; } // // Initialize the virtualized item pool // _virtualizedItemPool = new List<VirtualizedItem>(); _mediaStrip.Children.Clear(); for (int index = 0; index < _virtualizedItemPoolSize; index++) { VirtualizedItem virtualizedItem = new VirtualizedItem(new Size(_size.Value.Width, _size.Value.Height)); virtualizedItem.DataTemplate = ItemTemplate; virtualizedItem.ItemZoomed += OnItemZoomed; virtualizedItem.ItemUnzoomed += OnItemUnzoomed; _mediaStrip.Children.Add(virtualizedItem.RootFrameworkElement); _virtualizedItemPool.Add(virtualizedItem); } if (_state == MediaViewerState.Uninitialized) { _state = MediaViewerState.Initialized; } ResetDisplayedElement(); ResetItemLayout(); }
private void UpdateVirtualizedItemPositions() { int? itemIndexToCenterOn = null; switch (DisplayedElement) { case DisplayedElementType.Header: { if ((Items != null) && (Items.Count > 0)) { itemIndexToCenterOn = 0; } else { itemIndexToCenterOn = null; } } break; case DisplayedElementType.Item: { itemIndexToCenterOn = DisplayedItemIndex; } break; case DisplayedElementType.Footer: { if ((Items != null) && (Items.Count > 0)) { itemIndexToCenterOn = Items.Count - 1; } else { itemIndexToCenterOn = null; } } break; } if (itemIndexToCenterOn == null) { // There are valid cases where there are no items to virtualize in. return; } // Calculate the range of indexes we want the virtualized items to represent int itemsToEitherSide = _virtualizedItemPoolSize / 2; int firstIndex = Math.Max(0, itemIndexToCenterOn.Value - itemsToEitherSide); int lastIndex = Math.Min(Items.Count - 1, itemIndexToCenterOn.Value + itemsToEitherSide); for (int index = firstIndex; index <= lastIndex; index++) { bool isAlreadyVirtualizedIn = false; double correctPosition = CalculateItemOffset(index); VirtualizedItem repurposeCandidate = null; // Check to see if this item index is already virtualized in foreach (VirtualizedItem virtualizedItem in _virtualizedItemPool) { if ((DisplayedItemIndex != -1) && (virtualizedItem.RepresentingItemIndex == DisplayedItemIndex)) { _displayedVirtualizedItem = virtualizedItem; } if (virtualizedItem.RepresentingItemIndex == index) { isAlreadyVirtualizedIn = true; // Put it in the correct position if it isn't already there if ((double)virtualizedItem.RootFrameworkElement.GetValue(Canvas.LeftProperty) != correctPosition) { virtualizedItem.RootFrameworkElement.SetValue(Canvas.LeftProperty, correctPosition); } break; } else { if ((repurposeCandidate == null) || (virtualizedItem.RepresentingItemIndex == null)) { repurposeCandidate = virtualizedItem; } else if ((repurposeCandidate != null) && (repurposeCandidate.RepresentingItemIndex != null)) { // Look for the VirtualizedItem that is furthest from our itemIndexToCenterOn int existingDistance = Math.Abs((int)repurposeCandidate.RepresentingItemIndex.Value - (int)itemIndexToCenterOn); int thisDistance = Math.Abs((int)virtualizedItem.RepresentingItemIndex.Value - (int)itemIndexToCenterOn); if (thisDistance > existingDistance) { repurposeCandidate = virtualizedItem; } } } } if (!isAlreadyVirtualizedIn) { // Repurpose the repurposeCandidate to represent this item repurposeCandidate.DataContext = Items[(int)index]; repurposeCandidate.RepresentingItemIndex = index; repurposeCandidate.RootFrameworkElement.SetValue(Canvas.LeftProperty, correctPosition); repurposeCandidate.RootFrameworkElement.Visibility = System.Windows.Visibility.Visible; if ((DisplayedItemIndex != -1) && (repurposeCandidate.RepresentingItemIndex == DisplayedItemIndex)) { _displayedVirtualizedItem = repurposeCandidate; } } } }