From 37009d533742fe18f741c122fd72a8e020bdf5e5 Mon Sep 17 00:00:00 2001 From: Vincent Baaij Date: Tue, 3 Jun 2025 11:07:44 +0200 Subject: [PATCH] Refine logic that determines if the DataGrid data needs to be reloaded --- ...crosoft.FluentUI.AspNetCore.Components.xml | 20 +++++++++++ .../Demo/Shared/Pages/Menu/MenuPage.razor | 2 +- .../DataGrid/FluentDataGrid.razor.cs | 34 ++++++++++++++++++- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml index 3fdc8fed22..25afca1077 100644 --- a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml +++ b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml @@ -1241,6 +1241,12 @@ If not specified, the default header template includes the along with any applicable sort indicators and options buttons. + + + Gets or sets a template for the title content of this column's header cell. + If not specified, the default header template includes the . + + If specified, indicates that this column has this associated options UI. A button to display this @@ -1350,6 +1356,14 @@ respecting that option. + + + Gets or sets a that will be rendered for this column's header title. + This allows derived components to change the header title output. However, derived components are then + responsible for using within that new output if they want to continue + respecting that option. + + Gets a value indicating whether this column should act as sortable if no value was set for the @@ -2255,6 +2269,12 @@ + + + Computes a hash code for the given items. + To limit the effect on performance, only the given maximum number (default 250) of items will be considered. + + Gets or sets the reference to the item that holds this cell's values. diff --git a/examples/Demo/Shared/Pages/Menu/MenuPage.razor b/examples/Demo/Shared/Pages/Menu/MenuPage.razor index 8959ad3fc5..7c7d04775b 100644 --- a/examples/Demo/Shared/Pages/Menu/MenuPage.razor +++ b/examples/Demo/Shared/Pages/Menu/MenuPage.razor @@ -40,7 +40,7 @@

With version 4.9.4 of the library, we introduced the FluentMenuProvider component. The Menu component has been updated to use this provider. The <FluentMenuProvider /> needs to be placed at the bottom of your HTML page (just like the other ...Providers components). - It will renders all menus (and menu items) at the provider location in the HTML structure. This allows for menus to appear on top other components. + It will render all menus (and menu items) at the provider location in the HTML structure. This allows for menus to appear above of other components.

You can disable this feature by adding the UseMenuService parameter (with a value of "false") to you FluentMenu component. In this case, the menu will be rendered at the location it is placed at in the page. diff --git a/src/Core/Components/DataGrid/FluentDataGrid.razor.cs b/src/Core/Components/DataGrid/FluentDataGrid.razor.cs index f61872f2a1..9991e4f9ec 100644 --- a/src/Core/Components/DataGrid/FluentDataGrid.razor.cs +++ b/src/Core/Components/DataGrid/FluentDataGrid.razor.cs @@ -365,6 +365,7 @@ public partial class FluentDataGrid : FluentComponentBase, IHandleEve // things have changed, and to discard earlier load attempts that were superseded. private PaginationState? _lastRefreshedPaginationState; private IQueryable? _lastAssignedItems; + private int _lastAssignedItemsHashCode; private GridItemsProvider? _lastAssignedItemsProvider; private CancellationTokenSource? _pendingDataLoadCancellationTokenSource; @@ -425,14 +426,18 @@ protected override Task OnParametersSetAsync() throw new InvalidOperationException($"FluentDataGrid cannot use both {nameof(Virtualize)} and {nameof(MultiLine)} at the same time."); } + var currentItemsHash = FluentDataGrid.ComputeItemsHash(Items); + var itemsChanged = currentItemsHash != _lastAssignedItemsHashCode; + // Perform a re-query only if the data source or something else has changed - var dataSourceHasChanged = !Equals(Items, _lastAssignedItems) || !Equals(ItemsProvider, _lastAssignedItemsProvider); + var dataSourceHasChanged = itemsChanged || !Equals(ItemsProvider, _lastAssignedItemsProvider); if (dataSourceHasChanged) { _scope?.Dispose(); _scope = ScopeFactory.CreateAsyncScope(); _lastAssignedItemsProvider = ItemsProvider; _lastAssignedItems = Items; + _lastAssignedItemsHashCode = currentItemsHash; _asyncQueryExecutor = AsyncQueryExecutorSupplier.GetAsyncQueryExecutor(_scope.Value.ServiceProvider, Items); } @@ -1093,4 +1098,31 @@ public async Task ResetColumnWidthsAsync() await Module.InvokeVoidAsync("resetColumnWidths", _gridReference); } } + + ///

+ /// Computes a hash code for the given items. + /// To limit the effect on performance, only the given maximum number (default 250) of items will be considered. + /// + private static int ComputeItemsHash(IEnumerable? items, int maxItems = 250) + { + if (items == null) + { + return 0; + } + unchecked + { + var hash = 19; + var count = 0; + foreach (var item in items) + { + if (++count > maxItems) + { + break; + } + hash = (hash * 31) + (item?.GetHashCode() ?? 0); + } + return hash; + } + } } +