From c756dd53ce159144c14cfa182edab72e672699f5 Mon Sep 17 00:00:00 2001 From: Poker Date: Thu, 28 Nov 2024 16:16:40 +0800 Subject: [PATCH 1/3] Fix: StaggeredLayout division bug --- components/Primitives/src/StaggeredLayout/StaggeredLayout.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/Primitives/src/StaggeredLayout/StaggeredLayout.cs b/components/Primitives/src/StaggeredLayout/StaggeredLayout.cs index 384d0614..3253bd53 100644 --- a/components/Primitives/src/StaggeredLayout/StaggeredLayout.cs +++ b/components/Primitives/src/StaggeredLayout/StaggeredLayout.cs @@ -163,7 +163,7 @@ protected override Size MeasureOverride(VirtualizingLayoutContext context, Size if (ItemsStretch is StaggeredLayoutItemsStretch.None) { columnWidth = double.IsNaN(DesiredColumnWidth) ? availableWidth : Math.Min(DesiredColumnWidth, availableWidth); - numColumns = Math.Max(1, (int)Math.Floor(availableWidth / state.ColumnWidth)); + numColumns = Math.Max(1, (int)Math.Floor(availableWidth / columnWidth)); } else { From 2e64c30898d5e795dc71d970fb581fd9ce5cd0c7 Mon Sep 17 00:00:00 2001 From: Michael Hawker <24302614+michael-hawker@users.noreply.github.com> Date: Wed, 27 Nov 2024 13:42:42 -0800 Subject: [PATCH 2/3] Update tooling pointer Follow-on commmit for https://github.com/CommunityToolkit/Tooling-Windows-Submodule/pull/232 --- tooling | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tooling b/tooling index d71b08b2..eccfbc88 160000 --- a/tooling +++ b/tooling @@ -1 +1 @@ -Subproject commit d71b08b2dccf94c3ceaeda99526679bc0cfc3b8a +Subproject commit eccfbc8827bbf2de5df74d14b0f828ba8e19a2a1 From 044f82fa32cfa91e48cb1544d9ac7c42e064c43c Mon Sep 17 00:00:00 2001 From: Poker Date: Sat, 7 Dec 2024 04:27:02 +0800 Subject: [PATCH 3/3] Fix: prevent StaggeredLayout floating point errors (#573) * prevent floating point errors * fix spacing * Apply suggestions from code review Co-authored-by: Michael Hawker MSFT (XAML Llama) <24302614+michael-hawker@users.noreply.github.com> --------- Co-authored-by: Michael Hawker MSFT (XAML Llama) <24302614+michael-hawker@users.noreply.github.com> --- .../src/StaggeredLayout/StaggeredLayout.cs | 25 ++++++++++--------- .../StaggeredLayout/StaggeredLayoutState.cs | 8 +++--- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/components/Primitives/src/StaggeredLayout/StaggeredLayout.cs b/components/Primitives/src/StaggeredLayout/StaggeredLayout.cs index 3253bd53..28daed13 100644 --- a/components/Primitives/src/StaggeredLayout/StaggeredLayout.cs +++ b/components/Primitives/src/StaggeredLayout/StaggeredLayout.cs @@ -147,7 +147,7 @@ protected override Size MeasureOverride(VirtualizingLayoutContext context, Size return new Size(availableSize.Width, 0); } - if ((context.RealizationRect.Width == 0) && (context.RealizationRect.Height == 0)) + if (context.RealizationRect is { Width: 0, Height: 0 }) { return new Size(availableSize.Width, 0.0f); } @@ -163,7 +163,7 @@ protected override Size MeasureOverride(VirtualizingLayoutContext context, Size if (ItemsStretch is StaggeredLayoutItemsStretch.None) { columnWidth = double.IsNaN(DesiredColumnWidth) ? availableWidth : Math.Min(DesiredColumnWidth, availableWidth); - numColumns = Math.Max(1, (int)Math.Floor(availableWidth / columnWidth)); + numColumns = Math.Max(1, (int)Math.Floor(availableWidth / (columnWidth + ColumnSpacing))); } else { @@ -174,13 +174,14 @@ protected override Size MeasureOverride(VirtualizingLayoutContext context, Size } else { - var tempAvailableWidth = availableWidth + ColumnSpacing; - numColumns = (int)Math.Floor(tempAvailableWidth / DesiredColumnWidth); + // 0.0001 is to prevent floating point errors + var tempAvailableWidth = availableWidth + ColumnSpacing - 0.0001; + numColumns = (int)Math.Floor(tempAvailableWidth / (DesiredColumnWidth + ColumnSpacing)); columnWidth = tempAvailableWidth / numColumns - ColumnSpacing; } } - if (columnWidth != state.ColumnWidth) + if (Math.Abs(columnWidth - state.ColumnWidth) > double.Epsilon) { // The items will need to be remeasured state.Clear(); @@ -205,10 +206,10 @@ protected override Size MeasureOverride(VirtualizingLayoutContext context, Size state.ClearColumns(); } - if (RowSpacing != state.RowSpacing) + if (Math.Abs(this.RowSpacing - state.RowSpacing) > double.Epsilon) { // If the RowSpacing changes the height of the rows will be different. - // The columns stores the height so we'll want to clear them out to + // The columns store the height so we'll want to clear them out to // get the proper height state.ClearColumns(); state.RowSpacing = RowSpacing; @@ -228,7 +229,7 @@ protected override Size MeasureOverride(VirtualizingLayoutContext context, Size { // Item has not been measured yet. Get the element and store the values item.Element = context.GetOrCreateElementAt(i); - item.Element.Measure(new Size((float)state.ColumnWidth, (float)availableHeight)); + item.Element.Measure(new Size(state.ColumnWidth, availableHeight)); item.Height = item.Element.DesiredSize.Height; measured = true; } @@ -260,12 +261,12 @@ protected override Size MeasureOverride(VirtualizingLayoutContext context, Size deadColumns.Add(columnIndex); } - else if (measured == false) + else if (!measured) { // We ALWAYS want to measure an item that will be in the bounds item.Element = context.GetOrCreateElementAt(i); - item.Element.Measure(new Size((float)state.ColumnWidth, (float)availableHeight)); - if (item.Height != item.Element.DesiredSize.Height) + item.Element.Measure(new Size(state.ColumnWidth, availableHeight)); + if (Math.Abs(item.Height - item.Element.DesiredSize.Height) > double.Epsilon) { // this item changed size; we need to recalculate layout for everything after this state.RemoveFromIndex(i + 1); @@ -282,7 +283,7 @@ protected override Size MeasureOverride(VirtualizingLayoutContext context, Size double desiredHeight = state.GetHeight(); - return new Size((float)availableWidth, (float)desiredHeight); + return new Size(availableWidth, desiredHeight); } /// diff --git a/components/Primitives/src/StaggeredLayout/StaggeredLayoutState.cs b/components/Primitives/src/StaggeredLayout/StaggeredLayoutState.cs index 10b567a4..4ef319e0 100644 --- a/components/Primitives/src/StaggeredLayout/StaggeredLayoutState.cs +++ b/components/Primitives/src/StaggeredLayout/StaggeredLayoutState.cs @@ -91,14 +91,14 @@ internal void ClearColumns() /// /// The estimated height of the layout. /// - /// If all of the items have been calculated then the actual height will be returned. - /// If all of the items have not been calculated then an estimated height will be calculated based on the average height of the items. + /// If all the items have been calculated then the actual height will be returned. + /// If all the items have not been calculated then an estimated height will be calculated based on the average height of the items. /// internal double GetHeight() { - double desiredHeight = Enumerable.Max(_columnLayout.Values, c => c.Height); + double desiredHeight = _columnLayout.Values.Max(c => c.Height); - var itemCount = Enumerable.Sum(_columnLayout.Values, c => c.Count); + var itemCount = _columnLayout.Values.Sum(c => c.Count); if (itemCount == _context.ItemCount) { return desiredHeight;