From 745b12dd72bfb242654c262918a6e506454580e4 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Thu, 24 Sep 2020 10:39:09 +0100 Subject: [PATCH 1/2] Refresh when estimated item size changes. Fixes #25915 --- .../Web/src/Virtualization/Virtualize.cs | 43 +++++++++++++------ 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/Components/Web/src/Virtualization/Virtualize.cs b/src/Components/Web/src/Virtualization/Virtualize.cs index 02395e5abb8d..0a829a377a52 100644 --- a/src/Components/Web/src/Virtualization/Virtualize.cs +++ b/src/Components/Web/src/Virtualization/Virtualize.cs @@ -250,18 +250,18 @@ private string GetSpacerStyle(int itemsInSpacer) void IVirtualizeJsCallbacks.OnBeforeSpacerVisible(float spacerSize, float spacerSeparation, float containerSize) { - CalcualteItemDistribution(spacerSize, spacerSeparation, containerSize, out var itemsBefore, out var visibleItemCapacity); + CalcualteItemDistribution(spacerSize, spacerSeparation, containerSize, out var itemsBefore, out var visibleItemCapacity, out var itemSizeChanged); - UpdateItemDistribution(itemsBefore, visibleItemCapacity); + UpdateItemDistribution(itemsBefore, visibleItemCapacity, itemSizeChanged); } void IVirtualizeJsCallbacks.OnAfterSpacerVisible(float spacerSize, float spacerSeparation, float containerSize) { - CalcualteItemDistribution(spacerSize, spacerSeparation, containerSize, out var itemsAfter, out var visibleItemCapacity); + CalcualteItemDistribution(spacerSize, spacerSeparation, containerSize, out var itemsAfter, out var visibleItemCapacity, out var itemSizeChanged); var itemsBefore = Math.Max(0, _itemCount - itemsAfter - visibleItemCapacity); - UpdateItemDistribution(itemsBefore, visibleItemCapacity); + UpdateItemDistribution(itemsBefore, visibleItemCapacity, itemSizeChanged); } private void CalcualteItemDistribution( @@ -269,27 +269,37 @@ private void CalcualteItemDistribution( float spacerSeparation, float containerSize, out int itemsInSpacer, - out int visibleItemCapacity) + out int visibleItemCapacity, + out bool itemSizeChanged) { - if (_lastRenderedItemCount > 0) + if (spacerSeparation > 0 && _lastRenderedItemCount > 0) { + var previousItemSize = _itemSize; _itemSize = (spacerSeparation - (_lastRenderedPlaceholderCount * _itemSize)) / _lastRenderedItemCount; - } - if (_itemSize <= 0) + if (_itemSize <= 0) + { + // At this point, something unusual has occurred, likely due to misuse of this component. + // Reset the calculated item size to the user-provided item size. + _itemSize = ItemSize; + } + + // We don't want to create an infinite rendering loop due to floating point precision limits, + // so only re-render if the item size change is big enough + itemSizeChanged = Math.Abs(_itemSize - previousItemSize) > 0.5f; + } + else { - // At this point, something unusual has occurred, likely due to misuse of this component. - // Reset the calculated item size to the user-provided item size. - _itemSize = ItemSize; + itemSizeChanged = false; } itemsInSpacer = Math.Max(0, (int)Math.Floor(spacerSize / _itemSize) - OverscanCount); visibleItemCapacity = (int)Math.Ceiling(containerSize / _itemSize) + 2 * OverscanCount; } - private void UpdateItemDistribution(int itemsBefore, int visibleItemCapacity) + private void UpdateItemDistribution(int itemsBefore, int visibleItemCapacity, bool itemSizeChanged) { - if (itemsBefore != _itemsBefore || visibleItemCapacity != _visibleItemCapacity) + if (itemsBefore != _itemsBefore || visibleItemCapacity != _visibleItemCapacity || itemSizeChanged) { _itemsBefore = itemsBefore; _visibleItemCapacity = visibleItemCapacity; @@ -300,6 +310,13 @@ private void UpdateItemDistribution(int itemsBefore, int visibleItemCapacity) StateHasChanged(); } } + else if (itemSizeChanged) + { + // Even if the range of visible items hasn't changed, it's possible that we adjusted our + // estimate of the item height. In this case we need to re-render to update the spacer + // dimensions. + StateHasChanged(); + } } private async ValueTask RefreshDataCoreAsync(bool renderOnSuccess) From 303c2c1baf029eaae2bf0833945445ea0d97f139 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Thu, 24 Sep 2020 11:11:13 +0100 Subject: [PATCH 2/2] Remove typo --- src/Components/Web/src/Virtualization/Virtualize.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Web/src/Virtualization/Virtualize.cs b/src/Components/Web/src/Virtualization/Virtualize.cs index 0a829a377a52..ece0b8abdd0a 100644 --- a/src/Components/Web/src/Virtualization/Virtualize.cs +++ b/src/Components/Web/src/Virtualization/Virtualize.cs @@ -299,7 +299,7 @@ private void CalcualteItemDistribution( private void UpdateItemDistribution(int itemsBefore, int visibleItemCapacity, bool itemSizeChanged) { - if (itemsBefore != _itemsBefore || visibleItemCapacity != _visibleItemCapacity || itemSizeChanged) + if (itemsBefore != _itemsBefore || visibleItemCapacity != _visibleItemCapacity) { _itemsBefore = itemsBefore; _visibleItemCapacity = visibleItemCapacity;