使用RenderTreeBuilder来构建Blaor内置组件EditForm的渲染树

使用RenderTreeBuild渲染EidtorForm组件

背景

概要

最近看到ASP.NET微软文档的Forms部分,想用RenderTreeBuild手动构建组件树,使用EditorForm内置组件来实现表单功能。

环境

Blazor WASM .NET 6.0 C# 10.0

代码及说明

代码

以下为全部代码:

@using System.Linq.Expressions

@RenderForm()

@code {
    [Inject]
    public ILogger<StarshipPlainForm>? Logger { get; set; }

    public class Starship
    {
        public string? Id { get; set; }
    }

    private Starship? _starship { get; set; }

    private EditContext? _editContext;

    private Expression<Func<string>>? _idExpression;

    private EventCallback<string> ValueChanged { get; set; }

    private EventCallback<EditContext> OnSubmit { get; set; }

    protected override void OnInitialized()
    {
        // 初始化 _starship 实例
        _starship ??= new Starship { Id = "SKY-001" };

        // 创建编辑上下文
        _editContext = new EditContext(_starship);

        // 设置绑定表达式
        _idExpression = () => _starship!.Id!;

        ValueChanged = EventCallback.Factory.Create<string>(this, value => _starship!.Id = value);

        OnSubmit = EventCallback.Factory.Create<EditContext>(this, () => Logger.LogInformation("Starship Id = {Id}", _starship?.Id));
    }

    public RenderFragment RenderForm()
    {
        int sequence = 0;

        return builder =>
        {
            // 创建 EditForm 组件
            builder.OpenComponent<EditForm>(sequence++);
            builder.AddAttribute(sequence++, "EditContext", _editContext);
            builder.AddAttribute(sequence++, "OnSubmit", OnSubmit);

            // 创建 ChildContent 渲染块
            builder.AddAttribute(sequence++, "ChildContent", (RenderFragment<EditContext>)(context => tempBuilder =>
            {
                // 创建 InputText 组件绑定 Starship.Id
                tempBuilder.OpenComponent<InputText>(sequence++);
                tempBuilder.AddAttribute(sequence++, "Value", _starship?.Id);
                tempBuilder.AddAttribute(sequence++, "ValueChanged", ValueChanged);
                tempBuilder.AddAttribute(sequence++, "ValueExpression", _idExpression);

                // 关闭 InputText 组件
                tempBuilder.CloseComponent();

                // 添加提交按钮
                tempBuilder.AddMarkupContent(sequence++, "\r\n    ");
                tempBuilder.AddMarkupContent(sequence++, "<button type=\"submit\">Submit</button>");
            }));

            // 关闭 EditForm 组件
            builder.CloseComponent();
        };
    }
}

说明

变量名 类型 作用
_editContext EditContext 用于管理EditForm组件的表单上下文
OnSubmit EventCallback<EditContext> 用于处理EditForm的提交事件
_startship Starship 用于InputText组件的绑定数据源
_idExpression Expression<Func<string>>? 用于指定InputText的绑定表达式
ValueChanged EventCallback<string> 用于处理InputText组件的值更改事件

注:StarshipPlainForm为Razor组件名,或类名(组件就是类)。

    [Inject]
    public ILogger<StarshipPlainForm>? Logger { get; set; }

posted on 2025-01-24 14:50  wubing7755  阅读(51)  评论(0)    收藏  举报