diff --git a/src/BootstrapBlazor/Components/BaseComponents/DynamicElement.cs b/src/BootstrapBlazor/Components/BaseComponents/DynamicElement.cs index 367ec6a8136..385c6581832 100644 --- a/src/BootstrapBlazor/Components/BaseComponents/DynamicElement.cs +++ b/src/BootstrapBlazor/Components/BaseComponents/DynamicElement.cs @@ -10,13 +10,13 @@ namespace BootstrapBlazor.Components; /// /// 动态元素组件 -/// 动态元素component +/// Dynamic element component /// public class DynamicElement : BootstrapComponentBase { /// /// 获得/设置 TagName 属性 默认为 div - /// Gets or sets TagName property Default is为 div + /// Gets or sets the TagName property. Default is div /// [Parameter] [NotNull] @@ -24,77 +24,83 @@ public class DynamicElement : BootstrapComponentBase /// /// 获得/设置 是否触发 Click 事件 默认 true - /// Gets or sets whether触发 Click 事件 Default is true + /// Gets or sets whether to trigger Click event. Default is true /// [Parameter] public bool TriggerClick { get; set; } = true; /// /// 获得/设置 是否阻止默认行为 默认 false - /// Gets or sets whether阻止Default is行为 Default is false + /// Gets or sets whether to prevent default behavior. Default is false /// [Parameter] public bool PreventDefault { get; set; } /// /// 获得/设置 是否事件冒泡 默认为 false - /// Gets or sets whether事件冒泡 Default is为 false + /// Gets or sets whether to stop event propagation. Default is false /// [Parameter] public bool StopPropagation { get; set; } /// /// 获得/设置 Click 回调委托 - /// Gets or sets Click 回调delegate + /// Gets or sets the Click callback delegate /// [Parameter] public Func? OnClick { get; set; } /// /// 获得/设置 是否触发 DoubleClick 事件 默认 true - /// Gets or sets whether触发 DoubleClick 事件 Default is true + /// Gets or sets whether to trigger DoubleClick event. Default is true /// [Parameter] public bool TriggerDoubleClick { get; set; } = true; /// /// 获得/设置 DoubleClick 回调委托 - /// Gets or sets DoubleClick 回调delegate + /// Gets or sets the DoubleClick callback delegate /// [Parameter] public Func? OnDoubleClick { get; set; } /// /// 获得/设置 OnContextMenu 回调委托 - /// Gets or sets OnContextMenu 回调delegate + /// Gets or sets the OnContextMenu callback delegate /// [Parameter] public Func? OnContextMenu { get; set; } /// /// 获得/设置 是否触发 OnContextMenu 事件 默认 false - /// Gets or sets whether触发 OnContextMenu 事件 Default is false + /// Gets or sets whether to trigger OnContextMenu event. Default is false /// [Parameter] public bool TriggerContextMenu { get; set; } /// /// 获得/设置 内容组件 - /// Gets or sets contentcomponent + /// Gets or sets the child content /// [Parameter] public RenderFragment? ChildContent { get; set; } /// /// 获得/设置 是否生成指定 Tag 元素 默认 true 生成 - /// Gets or sets whether生成指定 Tag 元素 Default is true 生成 + /// Gets or sets whether to generate the specified Tag element. Default is true /// [Parameter] public bool GenerateElement { get; set; } = true; /// - /// BuildRenderTree 方法 - /// BuildRenderTree 方法 + /// 获得/设置 元素唯一标识 Key 默认 null + /// Gets or sets the unique key of the element. Default null + /// + [Parameter] + public object? Key { get; set; } + + /// + /// /// /// protected override void BuildRenderTree(RenderTreeBuilder builder) @@ -102,6 +108,11 @@ protected override void BuildRenderTree(RenderTreeBuilder builder) if (GenerateElement || IsTriggerClick() || IsTriggerDoubleClick()) { builder.OpenElement(0, TagName); + + if (Key != null) + { + builder.SetKey(Key); + } if (AdditionalAttributes != null) { builder.AddMultipleAttributes(1, AdditionalAttributes); @@ -111,26 +122,24 @@ protected override void BuildRenderTree(RenderTreeBuilder builder) if (IsTriggerClick()) { builder.AddAttribute(2, "onclick", EventCallback.Factory.Create(this, OnTriggerClick)); + builder.AddEventPreventDefaultAttribute(3, "onclick", PreventDefault); + builder.AddEventStopPropagationAttribute(4, "onclick", StopPropagation); } if (IsTriggerDoubleClick()) { - builder.AddAttribute(3, "ondblclick", EventCallback.Factory.Create(this, OnTriggerDoubleClick)); - } - - if (IsTriggerClick() || IsTriggerDoubleClick()) - { - builder.AddEventPreventDefaultAttribute(4, "onclick", PreventDefault); - builder.AddEventStopPropagationAttribute(5, "onclick", StopPropagation); + builder.AddAttribute(5, "ondblclick", EventCallback.Factory.Create(this, OnTriggerDoubleClick)); + builder.AddEventPreventDefaultAttribute(6, "ondblclick", PreventDefault); + builder.AddEventStopPropagationAttribute(7, "ondblclick", StopPropagation); } if (IsTriggerContextMenu()) { - builder.AddAttribute(6, "oncontextmenu", EventCallback.Factory.Create(this, OnTriggerContextMenu)); - builder.AddEventPreventDefaultAttribute(7, "oncontextmenu", true); + builder.AddAttribute(8, "oncontextmenu", EventCallback.Factory.Create(this, OnTriggerContextMenu)); + builder.AddEventPreventDefaultAttribute(9, "oncontextmenu", true); } - builder.AddContent(8, ChildContent); + builder.AddContent(10, ChildContent); if (GenerateElement || IsTriggerClick() || IsTriggerDoubleClick()) { diff --git a/test/UnitTest/Components/DynamicElementTest.cs b/test/UnitTest/Components/DynamicElementTest.cs new file mode 100644 index 00000000000..e088fd62888 --- /dev/null +++ b/test/UnitTest/Components/DynamicElementTest.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the Apache 2.0 License +// See the LICENSE file in the project root for more information. +// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone + +namespace UnitTest.Components; + +public class DynamicElementTest +{ + [Fact] + public void Key_OK() + { + var context = new BunitContext(); + var cut = context.Render(pb => + { + pb.Add(s => s.Key, Guid.NewGuid()); + }); + + Assert.Equal("
", cut.Markup); + } +} diff --git a/test/UnitTest/Core/TestBase.cs b/test/UnitTest/Core/TestBase.cs index d0aa0784255..d6b4c46c936 100644 --- a/test/UnitTest/Core/TestBase.cs +++ b/test/UnitTest/Core/TestBase.cs @@ -22,7 +22,7 @@ public void Dispose() #pragma warning disable CA2012 // 由于 bUnit 2.0 继承了 IAsyncDisposable 接口,因此此处调用 DisposeAsync 方法 Context.DisposeAsync(); -#pragma warning restore CA2012 +#pragma warning restore CA2012 GC.SuppressFinalize(this); } }