private void SetSize( ILayoutable element, double layoutItemWidth, double LayoutItemHeight, Size availableSize, UniformGridLayoutItemsStretch stretch, Orientation orientation, double minRowSpacing, double minColumnSpacing) { EffectiveItemWidth = (double.IsNaN(layoutItemWidth) ? element.DesiredSize.Width : layoutItemWidth); EffectiveItemHeight = (double.IsNaN(LayoutItemHeight) ? element.DesiredSize.Height : LayoutItemHeight); var availableSizeMinor = orientation == Orientation.Horizontal ? availableSize.Width : availableSize.Height; var minorItemSpacing = orientation == Orientation.Vertical ? minRowSpacing : minColumnSpacing; var itemSizeMinor = orientation == Orientation.Horizontal ? EffectiveItemWidth : EffectiveItemHeight; itemSizeMinor += minorItemSpacing; var numItemsPerColumn = (int)(Math.Max(1.0, availableSizeMinor / itemSizeMinor)); var remainingSpace = ((int)availableSizeMinor) % ((int)itemSizeMinor); var extraMinorPixelsForEachItem = remainingSpace / numItemsPerColumn; if (stretch == UniformGridLayoutItemsStretch.Fill) { if (orientation == Orientation.Horizontal) { EffectiveItemWidth += extraMinorPixelsForEachItem; } else { EffectiveItemHeight += extraMinorPixelsForEachItem; } } else if (stretch == UniformGridLayoutItemsStretch.Uniform) { var itemSizeMajor = orientation == Orientation.Horizontal ? EffectiveItemHeight : EffectiveItemWidth; var extraMajorPixelsForEachItem = itemSizeMajor * (extraMinorPixelsForEachItem / itemSizeMinor); if (orientation == Orientation.Horizontal) { EffectiveItemWidth += extraMinorPixelsForEachItem; EffectiveItemHeight += extraMajorPixelsForEachItem; } else { EffectiveItemHeight += extraMinorPixelsForEachItem; EffectiveItemWidth += extraMajorPixelsForEachItem; } } }
internal void EnsureElementSize( Size availableSize, VirtualizingLayoutContext context, double layoutItemWidth, double layoutItemHeight, UniformGridLayoutItemsStretch stretch, Orientation orientation, double minRowSpacing, double minColumnSpacing, int maxItemsPerLine) { if (maxItemsPerLine == 0) { maxItemsPerLine = 1; } if (context.ItemCount > 0) { // If the first element is realized we don't need to cache it or to get it from the context var realizedElement = FlowAlgorithm.GetElementIfRealized(0); if (realizedElement != null) { realizedElement.Measure(availableSize); SetSize(realizedElement, layoutItemWidth, layoutItemHeight, availableSize, stretch, orientation, minRowSpacing, minColumnSpacing, maxItemsPerLine); _cachedFirstElement = null; } else { if (_cachedFirstElement == null) { // we only cache if we aren't realizing it _cachedFirstElement = context.GetOrCreateElementAt( 0, ElementRealizationOptions.ForceCreate | ElementRealizationOptions.SuppressAutoRecycle); // expensive } _cachedFirstElement.Measure(availableSize); SetSize(_cachedFirstElement, layoutItemWidth, layoutItemHeight, availableSize, stretch, orientation, minRowSpacing, minColumnSpacing, maxItemsPerLine); // See if we can move ownership to the flow algorithm. If we can, we do not need a local cache. bool added = FlowAlgorithm.TryAddElement0(_cachedFirstElement); if (added) { _cachedFirstElement = null; } } } }
internal void EnsureElementSize( Size availableSize, VirtualizingLayoutContext context, double layoutItemWidth, double LayoutItemHeight, UniformGridLayoutItemsStretch stretch, Orientation orientation, double minRowSpacing, double minColumnSpacing) { if (context.ItemCount > 0) { // If the first element is realized we don't need to cache it or to get it from the context var realizedElement = FlowAlgorithm.GetElementIfRealized(0); if (realizedElement != null) { realizedElement.Measure(availableSize); SetSize(realizedElement, layoutItemWidth, LayoutItemHeight, availableSize, stretch, orientation, minRowSpacing, minColumnSpacing); _cachedFirstElement = null; } else { if (_cachedFirstElement == null) { // we only cache if we aren't realizing it _cachedFirstElement = context.GetOrCreateElementAt( 0, ElementRealizationOptions.ForceCreate | ElementRealizationOptions.SuppressAutoRecycle); // expensive } _cachedFirstElement.Measure(availableSize); // This doesn't need to be done in the UWP version and I'm not sure why. If we // don't do this here, and we receive a recycled element then it will be shown // at its previous arrange point, but we don't want it shown at all until its // arranged. _cachedFirstElement.Arrange(new Rect(-10000.0, -10000.0, 0, 0)); SetSize(_cachedFirstElement, layoutItemWidth, LayoutItemHeight, availableSize, stretch, orientation, minRowSpacing, minColumnSpacing); // See if we can move ownership to the flow algorithm. If we can, we do not need a local cache. bool added = FlowAlgorithm.TryAddElement0(_cachedFirstElement); if (added) { _cachedFirstElement = null; } } } }
internal void EnsureElementSize( Size availableSize, VirtualizingLayoutContext context, double layoutItemWidth, double LayoutItemHeight, UniformGridLayoutItemsStretch stretch, Orientation orientation, double minRowSpacing, double minColumnSpacing, uint maxItemsPerLine) { if (maxItemsPerLine == 0) { maxItemsPerLine = 1; } if (context.ItemCount > 0) { // If the first element is realized we don't need to get it from the context var realizedElement = m_flowAlgorithm.GetElementIfRealized(0); if (realizedElement is { })
internal void EnsureElementSize( Size availableSize, VirtualizingLayoutContext context, double layoutItemWidth, double LayoutItemHeight, UniformGridLayoutItemsStretch stretch, Orientation orientation, double minRowSpacing, double minColumnSpacing, uint maxItemsPerLine) { if (maxItemsPerLine == 0) { maxItemsPerLine = 1; } if (context.ItemCount > 0) { // If the first element is realized we don't need to get it from the context var realizedElement = FlowAlgorithm.GetElementIfRealized(0); if (realizedElement != null) { realizedElement.Measure(availableSize); SetSize(realizedElement.DesiredSize, layoutItemWidth, LayoutItemHeight, availableSize, stretch, orientation, minRowSpacing, minColumnSpacing, maxItemsPerLine); } else { // Not realized by flowlayout, so do this now! if (context.GetOrCreateElementAt(0, ElementRealizationOptions.ForceCreate) is { } firstElement) { firstElement.Measure(availableSize); SetSize(firstElement.DesiredSize, layoutItemWidth, LayoutItemHeight, availableSize, stretch, orientation, minRowSpacing, minColumnSpacing, maxItemsPerLine); context.RecycleElement(firstElement); } } } }
private void SetSize(UIElement UIElement, double layoutItemWidth, double LayoutItemHeight, Size availableSize, UniformGridLayoutItemsStretch stretch, Orientation orientation, double minRowSpacing, double minColumnSpacing, uint maxItemsPerLine) { if (maxItemsPerLine == 0) { maxItemsPerLine = 1; } EffectiveItemWidth = double.IsNaN(layoutItemWidth) ? UIElement.DesiredSize.Width : layoutItemWidth; EffectiveItemHeight = double.IsNaN(LayoutItemHeight) ? UIElement.DesiredSize.Height : LayoutItemHeight; var availableSizeMinor = orientation == Orientation.Horizontal ? availableSize.Width : availableSize.Height; var minorItemSpacing = orientation == Orientation.Vertical ? minRowSpacing : minColumnSpacing; var itemSizeMinor = orientation == Orientation.Horizontal ? EffectiveItemWidth : EffectiveItemHeight; double extraMinorPixelsForEachItem = 0.0; if (!double.IsInfinity(availableSizeMinor)) { var numItemsPerColumn = Math.Min( maxItemsPerLine, (uint)Math.Max(1.0, availableSizeMinor / (itemSizeMinor + minorItemSpacing))); var usedSpace = (numItemsPerColumn * (itemSizeMinor + minorItemSpacing)) - minorItemSpacing; var remainingSpace = ((int)(availableSizeMinor - usedSpace)); extraMinorPixelsForEachItem = remainingSpace / ((int)numItemsPerColumn); } if (stretch == UniformGridLayoutItemsStretch.Fill) { if (orientation == Orientation.Horizontal) { EffectiveItemWidth += extraMinorPixelsForEachItem; } else { EffectiveItemHeight += extraMinorPixelsForEachItem; } } else if (stretch == UniformGridLayoutItemsStretch.Uniform) { var itemSizeMajor = orientation == Orientation.Horizontal ? EffectiveItemHeight : EffectiveItemWidth; var extraMajorPixelsForEachItem = itemSizeMajor * (extraMinorPixelsForEachItem / itemSizeMinor); if (orientation == Orientation.Horizontal) { EffectiveItemWidth += extraMinorPixelsForEachItem; EffectiveItemHeight += extraMajorPixelsForEachItem; } else { EffectiveItemHeight += extraMinorPixelsForEachItem; EffectiveItemWidth += extraMajorPixelsForEachItem; } } }