在 blazor 中,通过自定义类的反射在属性信息循环上使用 @bind-checked

问题描述 投票:0回答:1

我有一个类 MyModel,它有超过 100 个属性(我知道),全都是 bool?数据类型。我试图为每个属性动态生成两个单选按钮(是/否),而不是手动为每个属性创建控件。我能够实现一些所需的输出,但无法将数据与验证绑定。编辑表单使用模型或编辑上下文,我都尝试过。 (使用syncfusion DataForm组件)

首先,我尝试仅循环反射的属性信息。

@foreach (var prop in properties)
{
<label>@prop.name</label>
<radio button value=true @[email protected](MyModel)>
<radio button value=false @[email protected](MyModel)>
}

接下来我尝试使用字典来存储字段名称和布尔值,但字典在这种情况下是只读的,并且不能双向绑定。

var dict = new Dictionary<PropertyInfo, bool?>;
(reflection here to set dictionary, setting bool? to null) 

@foreach (var kvp in dict)
{
<label>@kvp.Key.Name</label>
<radio button value=true @[email protected]>
<radio button value=false @[email protected]>
}

然后我更改了字典以包含“包装器”对象,以便可以更改值。这是有效的,除非我无法使用编辑上下文/模型进行验证。

var dict = new Dictionary<PropertyInfo, BoolWrapper?>;
@foreach (var kvp in dict)
{
<label>@kvp.Key.Name</label>
<radio button value=true @[email protected]>
<radio button value=false @[email protected]>
}

public class BoolWrapper
{
public bool? YesNo {get; set;}
}

我愿意接受任何关于如何实现这一目标的想法。我考虑过让模型类可索引,但我对 C# 还很陌生,它增加了很多我不太理解的复杂性。

非常感谢任何关于如何实现这一点的想法。

c# asp.net-core validation reflection blazor
1个回答
0
投票

以下样品可能满足您的需求:

@page "/"
@using System.Reflection
@rendermode InteractiveServer

<SfDataForm Model="PropertyVars" OnSubmit="HandleSubmit">
    <FormValidator>
        <DataAnnotationsValidator></DataAnnotationsValidator>
    </FormValidator>
    <FormItems>
        @foreach (var property in typeof(MyModel).GetProperties())
        {
            var propertyName = property.Name;
            <div>
                @propertyName
                <SfRadioButton Label="Yes" Name="@propertyName" Value="true" @bind-Checked="PropertyVars[propertyName]"></SfRadioButton>
                <SfRadioButton Label="No" Name="@propertyName" Value="false" @bind-Checked="PropertyVars[propertyName]"></SfRadioButton>
            </div>
        }
    </FormItems>
</SfDataForm>

@code{
    [SupplyParameterFromForm]
    public Dictionary<string, bool> PropertyVars { get; set; }

    private MyModel myModel = new();
    protected override void OnInitialized()
    {
        if (PropertyVars == null)
        {
            PropertyVars = new();
            foreach (var property in typeof(MyModel).GetProperties())
            {
                PropertyVars.Add(property.Name, false);
            }
        }
    }

    private void HandleSubmit()
    {
        foreach (var property in typeof(MyModel).GetProperties())
        {
            property.SetValue(myModel, PropertyVars[property.Name]);
        }
        var result = myModel;
    }

    public class MyModel
    {
        public bool bool1 { get; set; }    
        public bool bool2 { get; set; }
        public bool bool3 { get; set; }
    }
}

测试结果
enter image description here enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.