Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/BootstrapBlazor.Server/Locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -5008,6 +5008,7 @@
"TablesSearchTitle": "Table Search"
},
"BootstrapBlazor.Server.Components.Samples.Table.TablesSelection": {
"TablesSelectionCountText": "Count:{0}",
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The English string uses a full-width colon character (), which is inconsistent with the rest of en-US resources (e.g., "Keep State:") and may look incorrect in UI. Consider changing it to an ASCII colon and spacing (e.g., "Count: {0}").

Suggested change
"TablesSelectionCountText": "Count{0}",
"TablesSelectionCountText": "Count: {0}",

Copilot uses AI. Check for mistakes.
"TablesSelectionDescription": "Set the table row state by setting <code>SelectedRows</code>, and set the highlight by selecting the style",
"TablesSelectionKeepInfo": "Keep State:",
"TablesSelectionKeepOffText": "No keep",
Expand Down
1 change: 1 addition & 0 deletions src/BootstrapBlazor.Server/Locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -5008,6 +5008,7 @@
"TablesSearchTitle": "Table 表格"
},
"BootstrapBlazor.Server.Components.Samples.Table.TablesSelection": {
"TablesSelectionCountText": "选中的行数:{0}",
"TablesSelectionDescription": "通过设置 <code>SelectedRows</code> 设置表格行状态,通过选中样式可以设置高亮",
"TablesSelectionKeepInfo": "保持选中行状态:",
"TablesSelectionKeepOffText": "不保持",
Expand Down
2 changes: 1 addition & 1 deletion src/BootstrapBlazor/BootstrapBlazor.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<Version>10.3.2-beta02</Version>
<Version>10.3.2-beta03</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
3 changes: 2 additions & 1 deletion src/BootstrapBlazor/Components/Table/Table.razor.Checkbox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ protected CheckboxState HeaderCheckState()
/// <param name="val"></param>
protected virtual async Task OnHeaderCheck(CheckboxState state, TItem val)
{
SelectedRows.RemoveAll(Rows.Intersect(SelectedRows).Contains);
var items = Rows.Intersect(SelectedRows);
SelectedRows.RemoveAll(i => items.Any(item => Equals(item, i)));
Comment thread
ArgoZhang marked this conversation as resolved.
Comment on lines +108 to +109
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This predicate re-enumerates a deferred Intersect sequence for every element in SelectedRows, turning the removal into O(n*m) and repeatedly iterating SelectedRows while it is being mutated by RemoveAll. Materialize the rows-to-remove once (e.g., via ToList()/HashSet with an appropriate comparer) and then perform the removals against that snapshot.

Suggested change
var items = Rows.Intersect(SelectedRows);
SelectedRows.RemoveAll(i => items.Any(item => Equals(item, i)));
var items = new HashSet<TItem>(Rows.Intersect(SelectedRows));
SelectedRows.RemoveAll(i => items.Contains(i));

Copilot uses AI. Check for mistakes.
Comment on lines +108 to +109
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rows.Intersect(SelectedRows) uses EqualityComparer<TItem>.Default and will ignore the table's model equality logic (ModelEqualityComparer / CustomKeyAttribute / DynamicContext.EqualityComparer). This means some selected rows may not be removed correctly, so the change may not actually fix the reported selection mismatch.

Consider building the removal set using the table's model comparer (e.g., new ModelHashSetComparer<TItem>(this)) and then removing via HashSet.Contains, or otherwise ensure the intersection/removal uses Table.Equals(TItem,TItem) semantics throughout.

Suggested change
var items = Rows.Intersect(SelectedRows);
SelectedRows.RemoveAll(i => items.Any(item => Equals(item, i)));
// Build removal set using the table's model equality comparer to ensure
// that intersection logic respects custom model equality semantics.
var removalSet = new HashSet<TItem>(new ModelHashSetComparer<TItem>(this));
foreach (var row in Rows)
{
removalSet.Add(row);
}
SelectedRows.RemoveAll(i => removalSet.Contains(i));

Copilot uses AI. Check for mistakes.
if (state == CheckboxState.Checked)
{
SelectedRows.AddRange(ShowRowCheckboxCallback == null ? Rows : Rows.Where(ShowRowCheckboxCallback));
Expand Down