diff --git a/src/BootstrapBlazor/Components/Table/Table.razor b/src/BootstrapBlazor/Components/Table/Table.razor
index d69fc591142..0dcb3fcb52b 100644
--- a/src/BootstrapBlazor/Components/Table/Table.razor
+++ b/src/BootstrapBlazor/Components/Table/Table.razor
@@ -282,13 +282,15 @@
{
if (item is IDynamicObject d)
{
-
}
else
{
-
}
diff --git a/test/UnitTest/Components/TableTest.cs b/test/UnitTest/Components/TableTest.cs
index da165529237..b644c187b4a 100644
--- a/test/UnitTest/Components/TableTest.cs
+++ b/test/UnitTest/Components/TableTest.cs
@@ -8,6 +8,7 @@
using Microsoft.AspNetCore.Components.Web.Virtualization;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
+using System.Collections.Concurrent;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Reflection;
@@ -6474,6 +6475,126 @@ public async Task DynamicContext_EqualityComparer()
Assert.True(compared);
}
+ [Fact]
+ public async Task DynamicContext_CardView_CheckGuid_Ok()
+ {
+ var localizer = Context.Services.GetRequiredService>();
+ var selectedRows = new List();
+ var cut = Context.Render(pb =>
+ {
+ pb.AddChildContent>(pb =>
+ {
+ pb.Add(a => a.RenderMode, TableRenderMode.CardView);
+ pb.Add(a => a.IsMultipleSelect, true);
+ pb.Add(a => a.DynamicContext, CreateDynamicContext(localizer));
+ pb.Add(a => a.SelectedRows, selectedRows);
+ pb.Add(a => a.SelectedRowsChanged, EventCallback.Factory.Create>(this, rows => selectedRows = rows));
+ });
+ });
+
+ // CardView 模式无表头
+ // 共 2 行数据选中第一行数据
+ var input = cut.FindComponents>()[0];
+ await cut.InvokeAsync(input.Instance.OnToggleClick);
+
+ Assert.Single(selectedRows);
+ Assert.Equal(0, selectedRows[0].GetValue("Id"));
+
+ // 取消选中
+ await cut.InvokeAsync(input.Instance.OnToggleClick);
+ Assert.Empty(selectedRows);
+ }
+
+ [Fact]
+ public async Task DynamicContext_HeaderCheckGuid_Ok()
+ {
+ var localizer = Context.Services.GetRequiredService>();
+ var selectedRows = new List();
+ var cut = Context.Render(pb =>
+ {
+ pb.AddChildContent>(pb =>
+ {
+ pb.Add(a => a.RenderMode, TableRenderMode.Table);
+ pb.Add(a => a.IsMultipleSelect, true);
+ pb.Add(a => a.DynamicContext, CreateDynamicContext(localizer));
+ pb.Add(a => a.SelectedRows, selectedRows);
+ pb.Add(a => a.SelectedRowsChanged, EventCallback.Factory.Create>(this, rows => selectedRows = rows));
+ });
+ });
+
+ // 无选中行
+ Assert.Empty(selectedRows);
+
+ // 点击表头全选,选中行为 2 行
+ var header = cut.FindComponents>()[0];
+ await cut.InvokeAsync(header.Instance.OnToggleClick);
+ Assert.Equal(2, selectedRows.Count);
+
+ // 再次点击表头全选,取消全选
+ await cut.InvokeAsync(header.Instance.OnToggleClick);
+ Assert.Empty(selectedRows);
+ }
+
+ [Fact]
+ public async Task DynamicContext_HeaderCheckGuid_ShowRowCheckboxCallback_Ok()
+ {
+ // 测试包含无法选中行逻辑
+ var localizer = Context.Services.GetRequiredService>();
+ var selectedRows = new List();
+ var cut = Context.Render(pb =>
+ {
+ pb.AddChildContent>(pb =>
+ {
+ pb.Add(a => a.RenderMode, TableRenderMode.Table);
+ pb.Add(a => a.IsMultipleSelect, true);
+ pb.Add(a => a.DynamicContext, CreateDynamicContext(localizer));
+ pb.Add(a => a.ShowRowCheckboxCallback, row => Equals(row.GetValue("Id"), 0));
+ pb.Add(a => a.SelectedRows, selectedRows);
+ pb.Add(a => a.SelectedRowsChanged, EventCallback.Factory.Create>(this, rows => selectedRows = rows));
+ });
+ });
+
+ Assert.Equal(2, cut.FindComponents>().Count);
+
+ var header = cut.FindComponents>()[0];
+ await cut.InvokeAsync(header.Instance.OnToggleClick);
+ Assert.Single(selectedRows);
+ }
+
+
+ [Fact]
+ public async Task DynamicContext_ChangeDetection_Ok()
+ {
+ var localizer = Context.Services.GetRequiredService>();
+ var cut = Context.Render(pb =>
+ {
+ pb.AddChildContent>(pb =>
+ {
+ pb.Add(a => a.RenderMode, TableRenderMode.Table);
+ pb.Add(a => a.IsMultipleSelect, true);
+ pb.Add(a => a.DynamicContext, CreateDynamicContext(localizer));
+ });
+ });
+
+ cut.Dispose();
+
+ // 表格使用动态创建类型后,不能被 Blazor 底层 ChangeDetection 缓存,否则生成的动态 Assembly 无法被释放
+ // 通过反射查看是否被缓存
+ var type = typeof(ComponentBase).Assembly.GetType("Microsoft.AspNetCore.Components.ChangeDetection");
+ Assert.NotNull(type);
+
+ var fieldInfo = type.GetField("_immutableObjectTypesCache", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
+ Assert.NotNull(fieldInfo);
+
+ IEnumerable? items = null;
+ if (fieldInfo.GetValue(null) is ConcurrentDictionary cache)
+ {
+ items = cache.Keys.Where(i => i.Assembly.GetName().Name == "BootstrapBlazor_DynamicAssembly");
+ }
+ Assert.NotNull(items);
+ Assert.Empty(items);
+ }
+
[Fact]
public async Task DynamicContext_Add()
{