使用BlazorInputSelect
,您可以迭代组件ChildContent
中的列表项,但
我想创建一个自定义Blazor(WebAssembly版本5(InputSelect
,它可以接受要在select中呈现的任何对象的列表,代码可能如下所示:
<CustomInputSelect @bind-Value="@myEntity.CountryId" For="@(()=> myEntity.CountryId)" List="countries"
ValueField="@(a => a.Id)" DisplayField="@(a => a.CountryName)" ></CustomInputSelect>
甚至这个:
<CustomInputSelect @bind-Value="@myEntity.Country" For="@(()=> myEntity.Country)" List="countries"
ValueField="Id" DisplayField="CountryName" ></CustomInputSelect>
(注意:我使用For
属性来帮助编译器推断CountryId
的类型并进行验证。这是组件的@typeparam
。(
我尝试了很多方法,但都不起作用,所以我在下面解释它们:
我尝试使用
dynamic
类型作为列表,但Blazor似乎不支持动态类型,因为razor生成的代码中存在错误。我尝试将多个
@typeparam
用于组件,一个用于值,一个用作列表项。它似乎也不支持它。@继承InputSelect//或添加另一个typeparam@typeparam TListItem
和
<select>
@foreach (var item in List)
{
< option value="???">???</option >
}
</select>
@code{
[Parameter] public Expression<Func<TValue>>? For { get; set; }
[Parameter] public List<dynamic> List { get; set; }// or List<TListItem>
[Parameter] public Expression<Func<TListItem>>? ValueField { get; set; }
[Parameter] public Expression<Func<string>>? DisplayField { get; set; }
}
我的目标是向InputSelect
发送任何类型的列表,而@typeparam
用于绑定
我以前构建并使用过这个
@typeparam TItem
<div class="form-control-wrapper">
<select class="form-control-label" @onchange="ChangeHandler">
@if (ShowDefaultOption)
{
<option value="0" hidden disabled>- Please Select -</option>
}
@foreach (var (id, item) in idDictionary)
{
<option value="@id">@Selector(item).ToString()</option>
}
</select>
</div>
@code {
[Parameter] public IList<TItem> Items { get; set; }
[Parameter] public Func<TItem, object> Selector { get; set; }
[Parameter] public EventCallback<TItem> ValueChanged { get; set; }
[Parameter] public bool ShowDefaultOption { get; set; } = true;
private Dictionary<Guid, TItem> idDictionary;
protected override void OnInitialized()
{
idDictionary = new Dictionary<Guid, TItem>();
Items.ToList().ForEach(x => idDictionary.Add(Guid.NewGuid(), x));
}
private async Task ChangeHandler(ChangeEventArgs args)
{
if (idDictionary.TryGetValue(Guid.Parse(args.Value.ToString()), out var selectedItem))
{
await ValueChanged.InvokeAsync(selectedItem);
}
}
}
然后使用可以这样使用:
<MySelect ValueChanged="handleStringChange" TItem="string" Items="stringItems" Selector="(x => x)" />b
<p>@_selectedStringItem</p>
@code {
IList<string> stringItems = new List<string>()
{
"Random",
"String",
"Content",
"ForDemo"
};
string _selectedStringItem;
void handleStringChange(string value) => _selectedStringItem = value;
}
或者使用对象:
<MySelect ValueChanged="handleChange" TItem="Person" Items="items" Selector="(x => x.Firstname)" />
@if (_selectedItem is object)
{
<p>Selected person: Name: @_selectedItem.Firstname, Age: @_selectedItem.Age</p>
}
@code {
class Person
{
public string Firstname { get; set; }
public int Age { get; set; }
}
IList<Person> items = new List<Person>
{
new Person {Firstname = "John Doe", Age = 26},
new Person {Firstname = "Jane Doe", Age = 23}
};
Person _selectedItem;
void handleChange(Person value) => _selectedItem = value;
}