[英]Is there a way to do two-way binding in blazor inputtext dynamically
I am trying to create a reusable control.我正在尝试创建一个可重用的控件。 I have figured out how to handle the read-only scenarios using reflections with @typeof(TItem).GetProperty(col.PropertyName).GetValue(item)
我已经弄清楚如何使用@typeof(TItem).GetProperty(col.PropertyName).GetValue(item)
的反射来处理只读场景
And now I want to do the same with two-way binding Like <InputText @bind-Value="item.{select a property using the PropertyName value in ColumnDefinition}</InputText>"
现在我想对双向绑定做同样的事情,比如<InputText @bind-Value="item.{select a property using the PropertyName value in ColumnDefinition}</InputText>"
Is there a way to select the item's property using a string?有没有办法使用字符串 select 项目的属性?
Thanks!谢谢!
More references below:更多参考如下:
@typeparam TItem
<EditForm>
<table>
<thead>
<tr>
<Virtualize Items="ColumnDefinitions" Context="col">
<th>
@col.Caption
</th>
</Virtualize>
</tr>
</thead>
<tbody>
<Virtualize Items="Items" Context="item">
<tr>
<Virtualize Items="ColumnDefinitions" Context="col">
<td>
@typeof(TItem).GetProperty(col.PropertyName).GetValue(item)
<InputText @bind-Value=""></InputText>
</td>
</Virtualize>
</tr>
</Virtualize>
</tbody>
</table>
</EditForm>
@code {
[Parameter] public List<ColumnDefinition> ColumnDefinitions { get; set; }
[Parameter] public List<TItem> Items { get; set; }
}
public class ColumnDefinition
{
public short Order { get; set; }
public string Caption { get; set; }
public bool IsReadOnly { get; set; } = true;
public InputTypeEnum InputType { get; set; } = InputTypeEnum.Text;
public string PropertyName { get; set; }
}
You can get a value from a property on any object based on the name of the property itself.您可以根据属性本身的名称从任何 object 上的属性中获取值。
Example例子
public class Program
{
public static void Main()
{
var tst = new MyClass { MyProperty = 1 };
var propValue = tst.GetType().GetProperties().FirstOrDefault(p => p.Name == "MyProperty").GetValue(tst);
Console.WriteLine(propValue);
}
}
public class MyClass {
public int MyProperty { get;set; }
}
Now you can just adapt this solution to your case现在您可以根据您的情况调整此解决方案
<Virtualize Items="ColumnDefinitions" Context="col">
<td>
<InputText @bind-Value="@typeof(TItem).GetProperties().FirstOrDefault(p => p.Name == col.PropertyName).GetValue(item);"></InputText>
</td>
</Virtualize>
Hope this works, i dont work as much with razor files and cannot test this case right now, but at leats it can lead you to a solution希望这可行,我对 razor 文件的工作量不大,现在无法测试这种情况,但至少它可以引导您找到解决方案
In Blazor, a two-way binding consists of two steps.在 Blazor 中,双向绑定包括两个步骤。
To let the compiler do the magic, you use @bind-Value
instead of Value
.为了让编译器发挥作用,您可以使用@bind-Value
而不是Value
。 However, you could "hack" the system by setting the event handler by yourself.但是,您可以通过自己设置事件处理程序来“破解”系统。
<InputText
Value="@typeof(TItem).GetProperty(col.PropertyName).GetValue(item)"
ValueChanged="@(e => typeof(TItem).GetProperty(col.PropertyName).SetValue(item,e))">
</InputText>
As a reference, have a look at https://docs.microsoft.com/en-us/aspnet/core/blazor/components/data-binding?view=aspnetcore-5.0 .作为参考,请查看https://docs.microsoft.com/en-us/aspnet/core/blazor/components/data-binding?view=aspnetcore-5.0 。
<InputText>
is different from <input>
<InputText>
不同于<input>
<InputText>
requires Value
, ValueChanged
and ValueExpression
. <InputText>
需要Value
、 ValueChanged
和ValueExpression
。
@typeparam TItem
@using System.Linq.Expressions
<InputText Value="@Value"
ValueChanged="@ValueChanged"
ValueExpression="@ValueExpression"
class="form-control">
</InputText>
@code {
[Parameter] public TItem Item { get; set; }
[Parameter] public string PropertyName { get; set; }
private string Value;
private EventCallback<string> ValueChanged;
private Expression<Func<string>> ValueExpression;
protected override void OnInitialized()
{
Value = typeof(TItem).GetProperty(PropertyName).GetValue(Item).ToString();
ValueChanged = Microsoft.AspNetCore.Components.EventCallback.Factory.Create<System.String>(Item, Microsoft.AspNetCore.Components.EventCallback.Factory.CreateInferred(Item, _value => typeof(TItem).GetProperty(PropertyName).SetValue(Item, _value), (string)typeof(TItem).GetProperty(PropertyName).GetValue(Item)));
ValueExpression = Expression.Lambda<Func<string>>(Expression.Property(Expression.Constant(Item, typeof(TItem)), PropertyName));
}
}
Using the above component you can then do使用上面的组件,你可以做
<CustomInputText TItem="TItem" Item="item" PropertyName="@col.PropertyName">
Make sure to wrap in in <EditForm>
确保包含在<EditForm>
中
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.