use*_*669 4 c# data-binding components razor blazor
我正在尝试使用 Blazor 为类内的属性构建输入字段的动态列表,但无法弄清楚如何将输入框的内容绑定/链接到类的属性。(该类可以有大量的公共道具,不仅是下面例子中的 Name 和 Description,它们并不总是“string”类型)
可以说我有这个类/模型:
public class customer{
public string Name { get; set; }
public int Age { get; set; }
public string Description { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我得到了这个 blazor 组件(updateC.razor):
@inherits CLogic
@if (nfo != null)
{
@foreach (var obj in nfo)
{
<input type="text" class="form-control"
bind=@SCustomer.GetType().GetProperty(obj.ToString())/>
}
}
Run Code Online (Sandbox Code Playgroud)
最后是 Clogic:
public class Clogic: ComponentBase{
[Parameter]
public Customer SCustomer { get; set; } = new Customer();
[Parameter]
public PropertyInfo[] nfo { get; set; }
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
nfo = SCustomer.GetType().GetProperties();
StateHasChanged();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这假设将在每个输入字段中所做的更改绑定到 SCustomer 当前实例中的正确属性(当进行输入时,假设更新类/对象的正确属性)。这不起作用,输入完成后 SCustomer 中的值不会更改。我猜我要解决这个问题是完全错误的,但似乎无法弄清楚如何进行这项工作,也找不到任何这样做的例子。
@foreach (var propertyInfo in nfo)
{
<input type="text" class="form-control"
value="@propertyInfo.GetValue(SCustomer)"
@onchange="@((ChangeEventArgs __e) =>
propertyInfo.SetValue(SCustomer, __e.Value.ToString()))" />
}
Run Code Online (Sandbox Code Playgroud)
我终于找到了一种方法,这是我的解决方案:我创建了一个辅助类:
public class PropHolder
{
[Parameter]
public PropertyInfo info { get; set; }
[Parameter]
public string type { get; set; }
public PropHolder(PropertyInfo nfo, string propType)
{
info = nfo;
type = propType;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我创建了这个类的字典和一些检查函数(这是在Clogic内部)
[Parameter]
public Dictionary<int, PropHolder> Props{ get; set; }
public void GetAllProps()
{
Props = new Dictionary<int, PropHolder>();
//nfo = SCustomer.GetType().GetProperties();
int Cid = 0;
foreach (PropertyInfo pif in SCustomer.GetType().GetProperties())
{
Props[Cid] = new PropHolder(pif, pif.PropertyType.Name);
Cid++;
}
}
public string CheckName(PropHolder propertyInfo)
{
if (propertyInfo.GetType() == typeof(PropHolder))
{
return propertyInfo.type;
}
else
{
return propertyInfo.GetType().Name.ToString();
}
}
public PropertyInfo getInfo(PropHolder propertyInfo)
{
if (propertyInfo.GetType() == typeof(PropHolder))
{
return propertyInfo.info;
}
else
{
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
最后,我能够循环字典的键并正确绑定所有值(从“agua from mars”给出的答案中得到了很多帮助来解决这个问题)这里是 updateC.razor内容:
@if (Props != null)
{
@foreach (int key in Props.Keys)
{
var pinfo = Props[key];
@if (CheckName(pinfo) == "String")
{
<input type="text" class="form-control" value=@(getInfo(pinfo).GetValue(SCustomer)) @onchange="@((ChangeEventArgs __e) => getInfo(pinfo).SetValue(SCustomer, __e.Value.ToString()))" />
}
}
}
Run Code Online (Sandbox Code Playgroud)
这为我提供了每个 String 类型的 prop 的输入框,如果要处理其他类型,现在可以轻松添加。这可能不是最好的解决方案,但它确实有效。如果发布任何更好的工作解决方案,我将更新答案。