我正在嘗試遍歷模型并為模型中的每個屬性創建一個表單組件。我繼續遇到各種錯誤,需要一些幫助。以下是相關代碼:
表格.razor
<div class="form-section">
@foreach (var property in DataModel.GetType().GetProperties())
{
var propertyString = $"DataModel.{property.Name.ToString()}";
@if (property.PropertyType == typeof(DateTime))
{
<InputDate id=@"property.Name" @bind-Value="@propertyString">
}
else if (property.PropertyType == typeof(int))
{
<InputNumber id=@"property.Name" @bind-Value="@propertyString">
}
else
{
<InputText id=@"property.Name" @bind-Value="@propertyString">
}
}
</div>
資料模型.cs
public class DataModel
{
public DateTime SelectedData { get; set; }
public int SelectedNumber { get; set; }
public decimal SelectDecimal { get; set; }
}
Obviously, I've simplified the code greatly. The div in forms.razor shown above is nested in an EditForm element. This is looping through the properties of the class DataModel, and if the type is a DateTime, it should render an InputDate form, or an InputNumber form, etc. If there were only 3 properties I would just hard-code them, but in the actual application I have over 100 properties of either DateTime, int, or decimal types, so I'm looking for a more programmatic solution. My goal is to get this to check the type of each property in the class, then correctly render the appropriate form associate with that data type, bound to the correct property. Presently, I can only get the InputDate form to render, but when I enter a date in the form I get the following exception:
Error: System.InvalidOperationException: The type 'System.String' is not a supported date type
I'm guessing this is due to the fact that I'm passing in a string of the property name in the @bind-Value parameter of the InputDate component. I cannot figure out to pass the actual reference to the property though. Can anyone help me to hone in on how to resolve this issue?
uj5u.com熱心網友回復:
我認為@nocturns2 說的是正確的,你可以試試這個代碼:
@if (property.PropertyType == typeof(DateTime))
{
DateTime.TryParse(YourPropertyString, out var parsedValue);
var resutl= (YourType)(object)parsedValue
<InputDate id=@"property.Name" @bind-Value="@resutl">
}
uj5u.com熱心網友回復:
我終于想通了這一點。我最終在 onchange 屬性中使用了一個回呼,該回呼設定了回圈中當前屬性的值。
<div class="form-section">
@foreach (var property in DataModel.GetType().GetProperties())
{
var propertyString = $"DataModel.{property.Name.ToString()}";
@if (property.PropertyType == typeof(DateTime))
{
<input type="date" id="@property.Name" @onchange="@(e => property.SetValue(dataModel, DateTime.Parse(e.Value.ToString())))" />
}
else if (property.PropertyType == typeof(int))
{
<input type="number" id="@property.Name" @onchange="@(e => property.SetValue(dataModel, Int32.Parse(e.Value.ToString())))" />
}
else
{
<input type="number" id="@property.Name" @onchange="@(e => property.SetValue(dataModel, Decimal.Parse(e.Value.ToString())))" />
}
}
</div>
uj5u.com熱心網友回復:
這是一個組件化版本,其中包含 DateOnlyFields 的示例組件
@using System.Reflection
@using System.Globalization
<input type="date" value="@GetValue()" @onchange=this.OnChanged @attributes=UserAttributes />
@code {
[Parameter] [EditorRequired] public object? Model { get; set; }
[Parameter] [EditorRequired] public PropertyInfo? Property { get; set; }
[Parameter] public EventCallback ValueChanged { get; set; }
[Parameter(CaptureUnmatchedValues = true)] public IDictionary<string, object> UserAttributes { get; set; } = new Dictionary<string, object>();
private string GetValue()
{
var value = this.Property?.GetValue(Model);
return value is null
? DateTime.Now.ToString("yyyy-MM-dd")
: ((DateOnly)value).ToString("yyyy-MM-dd");
}
private void OnChanged(ChangeEventArgs e)
{
if (BindConverter.TryConvertToDateOnly(e.Value, CultureInfo.InvariantCulture, out DateOnly value))
this.Property?.SetValue(this.Model, value);
else
this.Property?.SetValue(this.Model, DateOnly.MinValue);
if (this.ValueChanged.HasDelegate)
this.ValueChanged.InvokeAsync();
}
}
并使用它:
@foreach (var property in dataModel.GetType().GetProperties())
{
@if (property.PropertyType == typeof(DateOnly))
{
<div class="form-text">
<DateOnlyEditor class="form-control" Model=this.dataModel Property=property ValueChanged=this.DataChanged />
</div>
}
}
<div class="p-3">
Date: @dataModel.SelectedDate
</div>
@code {
private DataModel dataModel = new DataModel();
private EditContext? editContext;
public class DataModel
{
public DateOnly SelectedDate { get; set; } = new DateOnly(2020, 12, 25);
public int SelectedNumber { get; set; }
public decimal SelectDecimal { get; set; }
}
protected override void OnInitialized()
{
this.editContext = new EditContext(dataModel);
base.OnInitialized();
}
void DataChanged()
{
StateHasChanged();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/441760.html
標籤:c# forms asp.net-core blazor blazor-server-side
上一篇:擬合給定2D輪廓的橢球
