我正在使用 MudBlazor 开发 Blazor 应用程序,并且在用于选择次要肌肉群的 MudSelect 组件方面遇到问题。当在单独的组件中选择主要肌肉群时,就会出现问题。
场景如下:
我有两个 MudSelect 组件:一个用于选择主要肌肉群,另一个用于选择多个次要肌肉群。 当未选择主要肌肉群时,辅助 MudSelect 可以正常工作,在关闭下拉列表时将所有选定的值显示为逗号分隔的字符串。
但是,当选择主要肌肉群时,辅助 MudSelect 的显示屏(关闭时)始终显示列表中的第一项(即“肩膀”),无论实际选择的是哪个辅助肌肉群。 如果我打开辅助 MudSelect 下拉列表,我可以看到选择了正确的项目;问题仅在于关闭下拉菜单时的显示。
这是我的针对次要肌肉群的 MudSelect 的简化版本:
<MudSelect T="MuscleGroups" Label="Secondary Muscle Groups" MultiSelection="true"
@bind-SelectedValues="SecondaryMuscleGroups"
Variant="Variant.Outlined">
@foreach (var muscleGroup in AvailableSecondaryMuscleGroups)
{
<MudSelectItem Value="@muscleGroup">@muscleGroup.ToString()</MudSelectItem>
}
</MudSelect>
任何见解或解决方案将不胜感激!
TryMudblazor 的问题工作示例:https://try.mudblazor.com/snippet/wYmeOivrMYvMBnYf
我曾与 ChatGTP、Claude 和 Github 副驾驶员争论过,但最终总是陷入兔子洞,导致复杂的代码无法解决问题..
看看你的片段。我认为导致问题的主要原因是在这一行
ToString()
中使用 <MudSelectItem Value="@muscleGroup">@muscleGroup.ToString()</MudSelectItem>
转换为字符串。虽然我确实对你的代码片段做了很多更改。
许多逻辑与实际属性相关,这非常令人困惑,特别是当您需要跟踪组件相对于 Blazor 生命周期的流程时。我建议使用生命周期方法,例如
OnInitialised
、OnAfterRender
等。来处理初始化属性和字段。
<MudPaper Class="p-4 max-w-screen-sm mx-auto" Elevation="2">
<MudForm @ref="form" Model="@newExercise" OnValidSubmit="HandleValidSubmit">
<MudSelect T="MuscleGroups" Label="Primary Muscle Group" Value="_primaryMuscleGroup" ValueChanged="OnPrimaryMuscleGroupChanged" Variant="Variant.Outlined">
@foreach (var muscleGroup in Enum.GetValues(typeof(MuscleGroups)))
{
<MudSelectItem Value="@((MuscleGroups)muscleGroup)">@muscleGroup.ToString()</MudSelectItem>
}
</MudSelect>
<MudSelect T="MuscleGroups" Label="Secondary Muscle Groups" MultiSelection="true"
SelectedValues="@_secondaryMuscleGroups"
SelectedValuesChanged="OnSecondaryMuscleGroupsChanged"
Variant="Variant.Outlined">
@foreach (var muscleGroup in SelectableSecGroups)
{
<MudSelectItem Value="@muscleGroup"/>
}
</MudSelect>
</MudForm>
</MudPaper>
@code {
private MudForm form;
private Exercise newExercise;
private MuscleGroups _primaryMuscleGroup;
private HashSet<MuscleGroups> _secondaryMuscleGroups;
private List<MuscleGroups> SelectableSecGroups;
protected override void OnInitialized(){
newExercise = new();
_primaryMuscleGroup = newExercise.PrimaryMuscleGroup;
_secondaryMuscleGroups = new HashSet<MuscleGroups>();
SelectableSecGroups = Enum.GetValues(typeof(MuscleGroups))
.Cast<MuscleGroups>().ToList();
UpdateAvailableSecondaryTargetedMuscles();
}
private void OnSecondaryMuscleGroupsChanged(IEnumerable<MuscleGroups> newSecondaryMuscleGroups) {
_secondaryMuscleGroups.Clear();
_secondaryMuscleGroups.UnionWith(newSecondaryMuscleGroups);
}
private void OnPrimaryMuscleGroupChanged(MuscleGroups newPrimaryMuscleGroup)
{
_primaryMuscleGroup = newPrimaryMuscleGroup;
UpdateAvailableSecondaryTargetedMuscles();
}
private void UpdateAvailableSecondaryTargetedMuscles()
{
if(_primaryMuscleGroup != MuscleGroups.Default) // assumed default should always be selectable
{
SelectableSecGroups = Enum.GetValues(typeof(MuscleGroups))
.Cast<MuscleGroups>()
.Where(mg => mg != _primaryMuscleGroup).ToList();
}
}
public class Exercise
{
public MuscleGroups PrimaryMuscleGroup { get; set; } = MuscleGroups.Default;
public List<MuscleGroups> SecondaryMuscleGroups { get; set; } = new List<MuscleGroups>();
}
public enum MuscleGroups
{
Shoulders,
Chest,
Biceps,
Triceps,
Forearms,
Abs,
Legs,
Core,
Back,
Calves,
Glutes,
Neck,
Default // Fallback for exercises that don’t fit neatly into other categories
}
}
演示 MudBlazor 片段