diff --git a/Directory.Build.props b/Directory.Build.props index 9c384ee84d..d0841c0543 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -22,7 +22,7 @@ 5.0.0 5.0.0 - alpha.1 + RC.2 Microsoft © Microsoft Corporation. All rights reserved. diff --git a/examples/Demo/FluentUI.Demo.Client/Documentation/Components/DataGrid/Examples/DataGridCustomComparer.razor b/examples/Demo/FluentUI.Demo.Client/Documentation/Components/DataGrid/Examples/DataGridCustomComparer.razor index 740da86225..36ba1753f6 100644 --- a/examples/Demo/FluentUI.Demo.Client/Documentation/Components/DataGrid/Examples/DataGridCustomComparer.razor +++ b/examples/Demo/FluentUI.Demo.Client/Documentation/Components/DataGrid/Examples/DataGridCustomComparer.razor @@ -35,6 +35,7 @@ Pagination="@pagination" TGridItem="Country" OnRowFocus="HandleRowFocus" + OnSortChanged="HandleSortChanged" GridTemplateColumns="0.2fr 1fr 0.2fr 0.2fr 0.2fr 0.2fr" ShowHover="true"> @@ -123,6 +124,11 @@ Console.WriteLine($"[Custom comparer] Row focused: {row.Item?.Name}"); } + private void HandleSortChanged(DataGridSortEventArgs args) + { + Console.WriteLine($"[Custom comparer] Sort changed: {args.Column?.Title} columns sorted {(args.SortByAscending ? "ascending" : "descending")}"); + } + public class StringLengthComparer : IComparer { public static readonly StringLengthComparer Instance = new StringLengthComparer(); diff --git a/src/Core/Components/DataGrid/FluentDataGrid.razor.cs b/src/Core/Components/DataGrid/FluentDataGrid.razor.cs index 35b6996eeb..4e63b8becb 100644 --- a/src/Core/Components/DataGrid/FluentDataGrid.razor.cs +++ b/src/Core/Components/DataGrid/FluentDataGrid.razor.cs @@ -305,6 +305,12 @@ public FluentDataGrid(LibraryConfiguration configuration) : base(configuration) [Parameter] public EventCallback OnCollapseAll { get; set; } + /// + /// Event callback for when the grid's sort order changes. + /// + [Parameter] + public EventCallback> OnSortChanged { get; set; } + /// /// Optionally defines a class to be applied to a rendered row. /// @@ -612,7 +618,7 @@ private void FinishCollectingColumns() /// The column that defines the new sort order. /// The direction of sorting. If the value is , then it will toggle the direction on each call. /// A representing the completion of the operation. - public Task SortByColumnAsync(ColumnBase column, DataGridSortDirection direction = DataGridSortDirection.Auto) + public async Task SortByColumnAsync(ColumnBase column, DataGridSortDirection direction = DataGridSortDirection.Auto) { _sortByAscending = direction switch { @@ -624,8 +630,17 @@ public Task SortByColumnAsync(ColumnBase column, DataGridSortDirectio _sortByColumn = column; + if (OnSortChanged.HasDelegate) + { + await OnSortChanged.InvokeAsync(new() + { + Column = _sortByColumn, + SortByAscending = _sortByAscending, + }); + } + _ = InvokeAsync(StateHasChanged); // We want to see the updated sort order in the header, even before the data query is completed - return RefreshDataAsync(); + await RefreshDataAsync(); } /// @@ -657,18 +672,26 @@ public Task SortByColumnAsync(int index, DataGridSortDirection direction = DataG /// /// The column to check against the current sorted on column. /// A representing the completion of the operation. - public Task RemoveSortByColumnAsync(ColumnBase column) + public async Task RemoveSortByColumnAsync(ColumnBase column) { if (_sortByColumn == column && !column.IsDefaultSortColumn) { _sortByColumn = _internalGridContext.DefaultSortColumn.Column ?? null; _sortByAscending = _internalGridContext.DefaultSortColumn.Direction != DataGridSortDirection.Descending; + if (OnSortChanged.HasDelegate) + { + await OnSortChanged.InvokeAsync(new() + { + Column = _sortByColumn, + SortByAscending = _sortByAscending + }); + } + _ = InvokeAsync(StateHasChanged); // We want to see the updated sort order in the header, even before the data query is completed - return RefreshDataCoreAsync(); + await RefreshDataCoreAsync(); + return; } - - return Task.CompletedTask; } /// diff --git a/src/Core/Events/DataGridSortEventArgs.cs b/src/Core/Events/DataGridSortEventArgs.cs new file mode 100644 index 0000000000..4bd2063b18 --- /dev/null +++ b/src/Core/Events/DataGridSortEventArgs.cs @@ -0,0 +1,22 @@ +// ------------------------------------------------------------------------ +// This file is licensed to you under the MIT License. +// ------------------------------------------------------------------------ + +namespace Microsoft.FluentUI.AspNetCore.Components; + +/// +/// Supplies information about a sort change event. +/// +/// The type of data represented by each row in the grid. +public class DataGridSortEventArgs : EventArgs +{ + /// + /// Gets the column that defines the sort order. + /// + public ColumnBase? Column { get; init; } + + /// + /// Gets a value indicating whether the grid is sorted ascending. + /// + public bool SortByAscending { get; init; } +} diff --git a/tests/Core/Components/DataGrid/FluentDataGridTests.razor b/tests/Core/Components/DataGrid/FluentDataGridTests.razor index 5cb308b1e6..6d3c1f586e 100644 --- a/tests/Core/Components/DataGrid/FluentDataGridTests.razor +++ b/tests/Core/Components/DataGrid/FluentDataGridTests.razor @@ -2320,4 +2320,50 @@ await cut.InvokeAsync(() => grid.RefreshDataAsync(force: true)); Assert.Equal(2, refreshCount); } + + [Fact] + public async Task FluentDataGrid_OnSortChanged_Fires() + { + // Arrange + var sortChanged = false; + DataGridSortEventArgs? eventArgs = null; + var customers = GetCustomers().AsQueryable(); + + var cut = Render>( + @ + + ); + + var grid = cut.Instance; + var column = grid._columns[0]; + + // Act + await cut.InvokeAsync(() => grid.SortByColumnAsync(column, DataGridSortDirection.Ascending)); + + // Assert + Assert.True(sortChanged); + Assert.Equal(column, eventArgs?.Column); + Assert.True(eventArgs?.SortByAscending); + + // Reset + sortChanged = false; + + // Act - toggle to Descending. direction = Auto means "toggle". + await cut.InvokeAsync(() => grid.SortByColumnAsync(column, DataGridSortDirection.Auto)); + + // Assert + Assert.True(sortChanged); + Assert.Equal(column, eventArgs?.Column); + Assert.False(eventArgs?.SortByAscending); + + // Reset + sortChanged = false; + + // Act - Remove sort + await cut.InvokeAsync(() => grid.RemoveSortByColumnAsync(column)); + + // Assert + Assert.True(sortChanged); + Assert.Null(eventArgs?.Column); + } }