Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
47cbc26
feat: 增加 Key 参数
ArgoZhang Aug 1, 2025
da33062
refactor: 使用回调方法 GetKeyByITem 获得行 Key 值
ArgoZhang Aug 1, 2025
e7dfe41
chore: bump version 9.6.5
ArgoZhang Aug 2, 2025
1a71e4c
feat: 增加 PdfOptions 配置项
ArgoZhang Oct 27, 2025
63ad92d
chore: bump version 9.6.6
ArgoZhang Oct 27, 2025
cce713e
refactor: 调整 IconTemplate 优先级别
ArgoZhang Oct 29, 2025
c8a6c7c
feat: 增加 ActionButtonTemplate 模板
ArgoZhang Oct 30, 2025
afa14bd
refactor: 增加条件
ArgoZhang Oct 30, 2025
be72b25
chore: bump version 9.6.7
ArgoZhang Oct 30, 2025
eed08c3
feat(IpAddress): support paste function (#7276)
ArgoZhang Dec 9, 2025
bfc8abb
chore: bump version 9.6.8
ArgoZhang Dec 9, 2025
943e0bb
feat(IpAddress): trigger ValueChanged on paste event (#7280)
ArgoZhang Dec 9, 2025
5260e88
chore: bump version 9.6.9
ArgoZhang Dec 9, 2025
044a84a
chore: 支持 Interop 参数
ArgoZhang Dec 9, 2025
77da6d8
chore: bump version 9.6.10
ArgoZhang Dec 9, 2025
924fcb8
feat: 增加 OnBeforeTreeItemClick 方法
ArgoZhang Dec 16, 2025
ffde92e
chore: bump version 9.6.11
ArgoZhang Dec 16, 2025
9fb4eda
refactor: 兼容嵌套问题
ArgoZhang Dec 18, 2025
ae0b16f
chore: bump version 9.6.12
ArgoZhang Dec 18, 2025
16782ef
feat: 支持端口
ArgoZhang Dec 18, 2025
740ebf1
chore: bump version 9.6-13-beta01
ArgoZhang Dec 18, 2025
1efed9a
chore: bump version 9.6.13
ArgoZhang Dec 18, 2025
8b0b637
feat(ZipArchiveService): add ArchiveDirectoryAsync method
ArgoZhang Dec 19, 2025
fd7a470
test: 增加单元测试
ArgoZhang Dec 19, 2025
69c80c2
chore: bump version 9.6.14
ArgoZhang Dec 19, 2025
f37c67a
Merge branch 'uni-lite' into dev-test
ArgoZhang Feb 7, 2026
95e1757
refactor: 增加 Key 参数
ArgoZhang Feb 7, 2026
3d21257
refactor: 取消冗余代码
ArgoZhang Feb 7, 2026
1874b20
revert: 撤销更改
ArgoZhang Feb 7, 2026
b711fd7
refactor: 移动 SetKey 位置
ArgoZhang Feb 7, 2026
4dbb91f
refactor: 调整序号
ArgoZhang Feb 7, 2026
50baf7c
test: 增加单元测试
ArgoZhang Feb 7, 2026
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
57 changes: 33 additions & 24 deletions src/BootstrapBlazor/Components/BaseComponents/DynamicElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,98 +10,109 @@ namespace BootstrapBlazor.Components;

/// <summary>
/// <para lang="zh">动态元素组件</para>
/// <para lang="en">动态元素component</para>
/// <para lang="en">Dynamic element component</para>
/// </summary>
public class DynamicElement : BootstrapComponentBase
{
/// <summary>
/// <para lang="zh">获得/设置 TagName 属性 默认为 div</para>
/// <para lang="en">Gets or sets TagName property Default is为 div</para>
/// <para lang="en">Gets or sets the TagName property. Default is div</para>
/// </summary>
[Parameter]
[NotNull]
public string? TagName { get; set; } = "div";

/// <summary>
/// <para lang="zh">获得/设置 是否触发 Click 事件 默认 true</para>
/// <para lang="en">Gets or sets whether触发 Click 事件 Default is true</para>
/// <para lang="en">Gets or sets whether to trigger Click event. Default is true</para>
/// </summary>
[Parameter]
public bool TriggerClick { get; set; } = true;

/// <summary>
/// <para lang="zh">获得/设置 是否阻止默认行为 默认 false</para>
/// <para lang="en">Gets or sets whether阻止Default is行为 Default is false</para>
/// <para lang="en">Gets or sets whether to prevent default behavior. Default is false</para>
/// </summary>
[Parameter]
public bool PreventDefault { get; set; }

/// <summary>
/// <para lang="zh">获得/设置 是否事件冒泡 默认为 false</para>
/// <para lang="en">Gets or sets whether事件冒泡 Default is为 false</para>
/// <para lang="en">Gets or sets whether to stop event propagation. Default is false</para>
/// </summary>
[Parameter]
public bool StopPropagation { get; set; }

/// <summary>
/// <para lang="zh">获得/设置 Click 回调委托</para>
/// <para lang="en">Gets or sets Click 回调delegate</para>
/// <para lang="en">Gets or sets the Click callback delegate</para>
/// </summary>
[Parameter]
public Func<Task>? OnClick { get; set; }

/// <summary>
/// <para lang="zh">获得/设置 是否触发 DoubleClick 事件 默认 true</para>
/// <para lang="en">Gets or sets whether触发 DoubleClick 事件 Default is true</para>
/// <para lang="en">Gets or sets whether to trigger DoubleClick event. Default is true</para>
/// </summary>
[Parameter]
public bool TriggerDoubleClick { get; set; } = true;

/// <summary>
/// <para lang="zh">获得/设置 DoubleClick 回调委托</para>
/// <para lang="en">Gets or sets DoubleClick 回调delegate</para>
/// <para lang="en">Gets or sets the DoubleClick callback delegate</para>
/// </summary>
[Parameter]
public Func<Task>? OnDoubleClick { get; set; }

/// <summary>
/// <para lang="zh">获得/设置 OnContextMenu 回调委托</para>
/// <para lang="en">Gets or sets OnContextMenu 回调delegate</para>
/// <para lang="en">Gets or sets the OnContextMenu callback delegate</para>
/// </summary>
[Parameter]
public Func<MouseEventArgs, Task>? OnContextMenu { get; set; }

/// <summary>
/// <para lang="zh">获得/设置 是否触发 OnContextMenu 事件 默认 false</para>
/// <para lang="en">Gets or sets whether触发 OnContextMenu 事件 Default is false</para>
/// <para lang="en">Gets or sets whether to trigger OnContextMenu event. Default is false</para>
/// </summary>
[Parameter]
public bool TriggerContextMenu { get; set; }

/// <summary>
/// <para lang="zh">获得/设置 内容组件</para>
/// <para lang="en">Gets or sets contentcomponent</para>
/// <para lang="en">Gets or sets the child content</para>
/// </summary>
[Parameter]
public RenderFragment? ChildContent { get; set; }

/// <summary>
/// <para lang="zh">获得/设置 是否生成指定 Tag 元素 默认 true 生成</para>
/// <para lang="en">Gets or sets whether生成指定 Tag 元素 Default is true 生成</para>
/// <para lang="en">Gets or sets whether to generate the specified Tag element. Default is true</para>
/// </summary>
[Parameter]
public bool GenerateElement { get; set; } = true;

/// <summary>
/// <para lang="zh">BuildRenderTree 方法</para>
/// <para lang="en">BuildRenderTree 方法</para>
/// <para lang="zh">获得/设置 元素唯一标识 Key 默认 null</para>
/// <para lang="en">Gets or sets the unique key of the element. Default null</para>
/// </summary>
[Parameter]
public object? Key { get; set; }

/// <summary>
/// <inheritdoc/>
/// </summary>
/// <param name="builder"></param>
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);
Expand All @@ -111,26 +122,24 @@ protected override void BuildRenderTree(RenderTreeBuilder builder)
if (IsTriggerClick())
{
builder.AddAttribute(2, "onclick", EventCallback.Factory.Create<MouseEventArgs>(this, OnTriggerClick));
builder.AddEventPreventDefaultAttribute(3, "onclick", PreventDefault);
builder.AddEventStopPropagationAttribute(4, "onclick", StopPropagation);
}

if (IsTriggerDoubleClick())
{
builder.AddAttribute(3, "ondblclick", EventCallback.Factory.Create<MouseEventArgs>(this, OnTriggerDoubleClick));
}

if (IsTriggerClick() || IsTriggerDoubleClick())
{
builder.AddEventPreventDefaultAttribute(4, "onclick", PreventDefault);
builder.AddEventStopPropagationAttribute(5, "onclick", StopPropagation);
builder.AddAttribute(5, "ondblclick", EventCallback.Factory.Create<MouseEventArgs>(this, OnTriggerDoubleClick));
builder.AddEventPreventDefaultAttribute(6, "ondblclick", PreventDefault);
builder.AddEventStopPropagationAttribute(7, "ondblclick", StopPropagation);
}

if (IsTriggerContextMenu())
{
builder.AddAttribute(6, "oncontextmenu", EventCallback.Factory.Create<MouseEventArgs>(this, OnTriggerContextMenu));
builder.AddEventPreventDefaultAttribute(7, "oncontextmenu", true);
builder.AddAttribute(8, "oncontextmenu", EventCallback.Factory.Create<MouseEventArgs>(this, OnTriggerContextMenu));
builder.AddEventPreventDefaultAttribute(9, "oncontextmenu", true);
}

builder.AddContent(8, ChildContent);
builder.AddContent(10, ChildContent);

if (GenerateElement || IsTriggerClick() || IsTriggerDoubleClick())
{
Expand Down
21 changes: 21 additions & 0 deletions test/UnitTest/Components/DynamicElementTest.cs
Original file line number Diff line number Diff line change
@@ -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<DynamicElement>(pb =>
{
pb.Add(s => s.Key, Guid.NewGuid());
});

Assert.Equal("<div></div>", cut.Markup);
}
}
2 changes: 1 addition & 1 deletion test/UnitTest/Core/TestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}