diff --git a/src/BootstrapBlazor.Server/Components/Samples/Table/TablesSelection.razor b/src/BootstrapBlazor.Server/Components/Samples/Table/TablesSelection.razor
index c7feea66befdd68fd6ef38638a292073abfd7c13..aee6ac4023188d74401d85d08c88d7b67d4f2302 100644
--- a/src/BootstrapBlazor.Server/Components/Samples/Table/TablesSelection.razor
+++ b/src/BootstrapBlazor.Server/Components/Samples/Table/TablesSelection.razor
@@ -9,7 +9,11 @@
Introduction="@Localizer["TablesSelectionNormalIntro"]"
Name="Normal">
-
+ 保持选中行状态:
+ 选中的行数:@SelectedItems.Count
+
+
diff --git a/src/BootstrapBlazor.Server/Components/Samples/Table/TablesSelection.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/Table/TablesSelection.razor.cs
index 6809e66602e7bbbf97b93df3a3bc9a5d9d5476e6..b9b5ba838f9e778cf0c8e26ad77b0ede94b12e45 100644
--- a/src/BootstrapBlazor.Server/Components/Samples/Table/TablesSelection.razor.cs
+++ b/src/BootstrapBlazor.Server/Components/Samples/Table/TablesSelection.razor.cs
@@ -19,6 +19,9 @@ public partial class TablesSelection
[NotNull]
private List? SelectedItems { get; set; }
+
+ private bool IsKeepSelectedRows;
+
private static IEnumerable PageItemsSource => new int[]
{
4,
diff --git a/src/BootstrapBlazor/Components/Table/Table.razor.Checkbox.cs b/src/BootstrapBlazor/Components/Table/Table.razor.Checkbox.cs
index afa6ee28d1ed2d086bed817f2d8a92acbfb734c9..e8fe798428dfaa17488cdf12df1fbc640782e9eb 100644
--- a/src/BootstrapBlazor/Components/Table/Table.razor.Checkbox.cs
+++ b/src/BootstrapBlazor/Components/Table/Table.razor.Checkbox.cs
@@ -18,6 +18,26 @@ public partial class Table
.AddClass(HeaderStyle.ToDescriptionString(), HeaderStyle != TableHeaderStyle.None)
.Build();
+ ///
+ /// 是否保持选择行,默认为否。
+ /// 最少要有一种行对比的回落机制,否则重新获取数据后无法还原选中状态。
+ /// 保持行状态回落机制(优先级从高到低):
+ ///
+ /// -
+ /// ModelEqualityComparer
+ ///
+ /// -
+ /// CustomKeyAttribute
+ ///
+ /// -
+ /// IEqualityComparer<TItem> Equals 重载方法
+ ///
+ ///
+ ///
+ [Parameter]
+ public bool IsKeepSelectedRows { get; set; } = false;
+
+
///
/// 获得 表头行是否选中状态
///
@@ -95,14 +115,16 @@ public partial class Table
{
case CheckboxState.Checked:
// select all
- SelectedRows.Clear();
+ SelectedRows.RemoveAll(x => Rows.Any(a => Equals(a, x)));
SelectedRows.AddRange(ShowRowCheckboxCallback == null ? Rows : Rows.Where(ShowRowCheckboxCallback));
+
await OnSelectedRowsChanged();
break;
case CheckboxState.UnChecked:
default:
// unselect all
- SelectedRows.Clear();
+ SelectedRows.RemoveAll(x => Rows.Any(a => Equals(a, x)));
+
await OnSelectedRowsChanged();
break;
}
diff --git a/src/BootstrapBlazor/Components/Table/Table.razor.Edit.cs b/src/BootstrapBlazor/Components/Table/Table.razor.Edit.cs
index 82b2247aef3b421a558528855332d5630b0f8ae8..5bf89ec26e9a4747a6646ddc103b2c0b879b3f64 100644
--- a/src/BootstrapBlazor/Components/Table/Table.razor.Edit.cs
+++ b/src/BootstrapBlazor/Components/Table/Table.razor.Edit.cs
@@ -451,8 +451,11 @@ public partial class Table
IsAdvanceSearch = queryData.IsAdvanceSearch;
QueryItems = queryData.Items ?? Enumerable.Empty();
- // 处理选中行逻辑
- ResetSelectedRows(QueryItems);
+ if (!IsKeepSelectedRows)
+ {
+ // 处理选中行逻辑
+ ResetSelectedRows(QueryItems);
+ }
// 分页情况下内部不做处理防止页码错乱
ProcessData();
diff --git a/src/BootstrapBlazor/Components/Table/Table.razor.Pagination.cs b/src/BootstrapBlazor/Components/Table/Table.razor.Pagination.cs
index 6a25a5e9e8079144d907fa64186ed1ff6a580e74..d9a060ae783e2ddc02175bb3d1eb164fa95d720e 100644
--- a/src/BootstrapBlazor/Components/Table/Table.razor.Pagination.cs
+++ b/src/BootstrapBlazor/Components/Table/Table.razor.Pagination.cs
@@ -139,8 +139,11 @@ public partial class Table
{
PageIndex = pageIndex;
- // 清空选中行
- SelectedRows.Clear();
+ if (!IsKeepSelectedRows)
+ {
+ // 清空选中行
+ SelectedRows.Clear();
+ }
// 无刷新查询数据
await QueryAsync(false);
diff --git a/test/UnitTest/Components/TableTest.cs b/test/UnitTest/Components/TableTest.cs
index adcc2ded732ebb61758c520f2e5efe1465b6a21d..beb17500781f0e3ff57d2031f9c74e8987e5d5ef 100644
--- a/test/UnitTest/Components/TableTest.cs
+++ b/test/UnitTest/Components/TableTest.cs
@@ -4129,6 +4129,91 @@ public class TableTest : TableTestBase
Assert.Empty(checkboxs);
}
+ [Fact]
+ public async Task KeepSelectedRows_Ok()
+ {
+ var localizer = Context.Services.GetRequiredService>();
+ var Items = Foo.GenerateFoo(localizer, 6);
+ var cut = Context.RenderComponent(pb =>
+ {
+ pb.AddChildContent>(pb =>
+ {
+ pb.Add(a => a.RenderMode, TableRenderMode.Table);
+ pb.Add(a => a.IsMultipleSelect, true);
+ pb.Add(a => a.IsPagination, true);
+ pb.Add(a => a.IsKeepSelectedRows, true);
+ pb.Add(a => a.PageItemsSource, new int[] { 2 });
+ pb.Add(a => a.OnQueryAsync, options =>
+ {
+ var total = Items.Count;
+ var items = Items.Skip((options.PageIndex - 1) * options.PageItems).Take(options.PageItems).ToList();
+ return Task.FromResult(new QueryData() { Items = items, TotalCount = total, IsSorted = true, IsFiltered = true, IsSearch = true });
+ });
+ pb.Add(a => a.TableColumns, foo => builder =>
+ {
+ builder.OpenComponent>(0);
+ builder.AddAttribute(1, "Field", "Name");
+ builder.AddAttribute(2, "FieldExpression", Utility.GenerateValueExpression(foo, "Name", typeof(string)));
+ builder.CloseComponent();
+ });
+ });
+ });
+
+ var btn = cut.Find("tbody tr td input");
+ await cut.InvokeAsync(() => btn.Click());
+
+ var checkboxs = cut.FindAll(".is-checked");
+ Assert.Single(checkboxs);
+
+ //点击下页按钮翻页
+ var nextBtn = cut.Find(".fa-angle-right");
+ await cut.InvokeAsync(() => nextBtn.Click());
+
+ //选中行数为空
+ checkboxs = cut.FindAll(".is-checked");
+ Assert.Empty(checkboxs);
+
+ //点击下页按钮翻页
+ await cut.InvokeAsync(() => nextBtn.Click());
+
+ //点击表头CheckBox
+ btn = cut.Find("thead tr th input");
+ await cut.InvokeAsync(() => btn.Click());
+
+ //加上表头的复选框选中,结果有3项
+ checkboxs = cut.FindAll(".is-checked");
+ Assert.Equal(3, checkboxs?.Count);
+
+ //点击向前按钮翻页
+ var prevBtn = cut.Find("i.fa-angle-left");
+ await cut.InvokeAsync(() => prevBtn.Click());
+
+ //恢复选中行数为0
+ checkboxs = cut.FindAll(".is-checked");
+ Assert.Empty(checkboxs);
+
+ //点击向前按钮翻页
+ await cut.InvokeAsync(() => prevBtn.Click());
+
+ //恢复选中行数为1
+ checkboxs = cut.FindAll(".is-checked");
+ Assert.Single(checkboxs);
+
+ //点击向后翻页按钮
+ await cut.InvokeAsync(() => nextBtn.Click());
+
+ //恢复选中行数为0
+ checkboxs = cut.FindAll(".is-checked");
+ Assert.Empty(checkboxs);
+
+ //点击向后翻页按钮
+ await cut.InvokeAsync(() => nextBtn.Click());
+
+ //恢复选中行数为2,加上表头的复选框选中,结果有3项
+ checkboxs = cut.FindAll(".is-checked");
+ Assert.Equal(3, checkboxs?.Count);
+ }
+
[Fact]
public void TableColumn_Ok()
{