我正在尝试编写 MudSelect 下拉菜单的通用组件。组件的选项从父级传递过来,当所选选项发生变化时,我希望获取选项中定义的值(一个类)并导航到定义的页面。
以下是代码
HomePage.razor
<HomeContainerComponent>
<div>
<HomeDropdownComponent Options="@dropdownOptions" TValue="string" SelectedOption="@selectedOption" OnValueChanged="OnValueChanged" SelectedOptionChanged="SelectedOptionChanged"></HomeDropdownComponent>
</div>
</<HomeContainerComponent>
HomePage.razor.cs
using Microsoft.AspNetCore.Components;
namespace Test.Shared.Components.Pages
{
public partial class HomePage :ComponentBase
{
[Inject] private NavigationManager? NavigationManager { get; set; }
protected List<DropdownOptions<string>> dropdownOptions { get; set; } = new();
public DropdownOptions<string> selectedOption { get; set; } = new();
protected override void OnInitialized()
{
dropdownOptions = FetchDropdownOptions();
selectedOption = dropdownOptions?.FirstOrDefault() ?? new();
}
private List<DropdownOptions<string>> FetchDropdownOptions()
{
return dropdownOptions = new List<DropdownOptions<string>>
{
new DropdownOptions<string> { Value = "Option1", Text = "Option1" ,ImageUrl ="_content/Test.Shared.Components/option1.png"},
new DropdownOptions<string> { Value = "Option2", Text = "Option2" ,ImageUrl ="_content/Test.Shared.Components/option2.png"},
new DropdownOptions<string> { Value = "Option3", Text = "Option3" ,ImageUrl ="_content/Test.Shared.Components/option3.png" , PageName = "/mud-tab"},
new DropdownOptions<string> { Value = "Option4", Text = "Option4" ,ImageUrl ="_content/Test.Shared.Components/option3.png"},
};
}
private void OnValueChanged(string selected)
{
selectedOption = dropdownOptions?.Where( x => x.Text == selected).FirstOrDefault() ?? new();
NavigationManager?.NavigateTo(selectedOption.PageName);
// Do other stuff
}
}
public class DropdownOptions<T>
{
public T Value { get; set; } = default!;
public string Text { get; set; } = string.Empty;
public string Icon { get; set; } = string.Empty;
public string ImageUrl { get; set; } = string.Empty;
public string PageName { get; set; } = string.Empty;
}
}
HomeDropdownComponent.razor
@typeparam TValue
<MudSelect T="TValue" Label="@Label" Variant="@Variant" AnchorOrigin="@AnchorOrigin" ValueChanged="OnSelectedValueChanged">
@foreach (var option in Options)
{
<MudSelectItem T="TValue" Value="@(option.Value)">
@if (!string.IsNullOrEmpty(option.Icon))
{
<MudIcon Icon="@option.Icon" Class="mr-2" />
}
@if (!string.IsNullOrEmpty(option.ImageUrl))
{
<MudImage Src="@option.ImageUrl" Class="ml-2" />
}
@option.Text
<div style="flex-grow: 1"></div>
</MudSelectItem>
}
</MudSelect>
HomeDropdownComponent.razor.cs
using Microsoft.AspNetCore.Components;
using MudBlazor;
namespace Test.Shared.Components
{
public partial class HomeDropdownComponent<TValue>
{
[Parameter]
public string Label { get; set; } = string.Empty;
[Parameter]
public string Placeholder { get; set; } = string.Empty;
[Parameter]
public List<DropdownOptions<TValue>> Options { get; set; } = new();
[Parameter]
public DropdownOptions<TValue> SelectedOption { get; set; } = default!;
[Parameter]
public EventCallback<TValue> OnValueChanged { get; set; } = default!;
[Parameter]
public Variant Variant { get; set; } = Variant.Outlined;
public Origin AnchorOrigin = Origin.BottomCenter;
private TValue Value = default!;
private async Task OnSelectedValueChanged()
{
if (OnValueChanged.HasDelegate)
await OnValueChanged.InvokeAsync();
}
}
}
当我运行代码时,默认情况下不选择任何值,valuechanged 函数也返回 null。我的要求是当下拉值改变时获取页面的值并导航到该页面,如果我使用,则
<MudSelect T="TValue" Label="@Label" @bind-Value="SelectedOption.Value" Variant="@Variant" AnchorOrigin="@AnchorOrigin" >
选择第一个下拉值。
如果如果使用<MudSelect T="TValue" Label="@Label" @bind-Value="SelectedOption.Value" Variant="@Variant" AnchorOrigin="@AnchorOrigin" ValueChanged = "OnSelectedValueChanged">
它显示错误 ValueChanged 被使用了多次。
Value 属性需要分配给
MudSelect
并且您需要
EventCallback<TValue>
在调用它时将改变的值传递给它。如果您没有将其包装
MudSelect
在另一个组件中,那么您需要确保分配给的字段Value
需要在处理程序方法中更改。例如但是,由于它是一个子组件,因此父组件(
HomeDropdownComponent.razor
)应该处理改变SelectedOption.Value
。这是一个简化的例子。
演示👉MudBlazor代码片段