diff --git a/src/Core/Components/DataGrid/Columns/SelectColumn.cs b/src/Core/Components/DataGrid/Columns/SelectColumn.cs index c2e098a9ce..a5aa7b1229 100644 --- a/src/Core/Components/DataGrid/Columns/SelectColumn.cs +++ b/src/Core/Components/DataGrid/Columns/SelectColumn.cs @@ -209,6 +209,15 @@ public DataGridSelectMode SelectMode [Parameter] public override IGridSort? SortBy { get; set; } + /// + /// Gets or sets the equality comparer used to determine whether two grid items are equal. + /// + /// If not set, the default equality comparer for is used. + /// Setting this property allows customization of how grid items are compared for equality, which can affect + /// operations such as selection, filtering, or updating items in the grid. + [Parameter] + public IEqualityComparer? Comparer { get; set; } = null; + /// /// Allows to clear the selection. /// @@ -296,14 +305,21 @@ private async Task AddOrRemoveSelectedItemAsync(TGridItem? item) { if (item != null && (Selectable == null || Selectable.Invoke(item))) { - if (SelectMode is DataGridSelectMode.SingleSticky && _selectedItems.Contains(item)) + if (_selectedItems.Contains(item, Comparer)) { - return; - } - - if (SelectedItems.Contains(item)) - { - _selectedItems.Remove(item); + if (SelectMode is DataGridSelectMode.SingleSticky) + { + return; + } + if (Comparer != null) + { + var toRemove = _selectedItems.First(i => Comparer.Equals(i, item)); + _selectedItems.Remove(toRemove); + } + else + { + _selectedItems.Remove(item); + } SelectAll = false; await CallOnSelectAsync(item, false); } @@ -340,13 +356,12 @@ Task CallOnSelectAsync(TGridItem item, bool isSelected) private async Task UpdateSelectedItemsAsync() { - - if (!SelectedItems.Any() || InternalGridContext == null || InternalGridContext.Items == null) + if (_selectedItems.Count == 0 || InternalGridContext == null || InternalGridContext.Items == null) { return; } - var itemsToRemove = _selectedItems.Where(item => !InternalGridContext.Items.Contains(item)).ToList(); + var itemsToRemove = _selectedItems.Where(item => !InternalGridContext.Items.Contains(item, Comparer)).ToList(); foreach (var item in itemsToRemove) { await AddOrRemoveSelectedItemAsync(item); @@ -414,15 +429,16 @@ private RenderFragment GetDefaultChildContent() return; } - var selected = _selectedItems.Contains(item) || Property.Invoke(item); + var contained = _selectedItems.Contains(item, Comparer); + var selected = contained || Property.Invoke(item); // Sync with SelectedItems list - if (selected && !_selectedItems.Contains(item)) + if (selected && !contained) { _selectedItems.Add(item); RefreshHeaderContent(); } - else if (!selected && _selectedItems.Contains(item)) + else if (!selected && contained) { _selectedItems.Remove(item); } @@ -508,23 +524,16 @@ private void RefreshHeaderContent() // Using SelectedItems only if (InternalGridContext != null && (Grid.Items != null || Grid.ItemsProvider != null)) { - if (!SelectedItems.Any()) + if (_selectedItems.Count == 0) { return false; } - else if (SelectedItems.Count() == InternalGridContext.TotalItemCount || SelectAll == true) + else if (_selectedItems.Count == InternalGridContext.TotalItemCount || SelectAll == true) { return true; } - else - { - return null; - } - } - else - { - return null; } + return null; } /// @@ -555,13 +564,13 @@ internal async Task OnClickAllAsync(MouseEventArgs e) await SelectAllChanged.InvokeAsync(SelectAll); } - var count = SelectedItems.Count(); // SelectedItems + var count = _selectedItems.Count; _selectedItems.Clear(); if (SelectAll == true && count != InternalGridContext.TotalItemCount) { // Only add selectable items - _selectedItems.AddRange((InternalGridContext.Grid.Items?.ToList() ?? InternalGridContext.Items) + _selectedItems.AddRange(InternalGridContext.Items .Where(item => Selectable?.Invoke(item) ?? true) ); }