Blazor实现下拉选雇用时更新标签并禁用已选选项问题
Blazor 雇用人分配实现方案
核心需求
- 将NPC雇用人通过下拉菜单分配给对应Hex区域下的建筑/设施
- 选中雇用人后更新对应位置的标签文本
- 已分配的雇用人在其他所有下拉菜单中被移除或禁用
修改后的完整代码
<table class="w-50"> @foreach (var hxs in HexName) { <tr> <td colspan="2"><h3>@hxs.HexName Hex</h3></td> </tr> @foreach (var imps in Improvment.Where(imp => imp.ImprovementHex == hxs.HexName)) { <tr> <td colspan="2">@imps.ImprovementName - @imps.ImprovementMaterial</td> </tr> @foreach (var assignment in Assignments.Where(a => a.ImprovementId == imps.ImprovementId)) { <tr> <td class="p-3"> <select class="form-select" @bind="assignment.SelectedHirelingId" @onchange="() => UpdateAssignment(assignment)"> <option value="">未分配</option> @foreach (var hire in AvailableHirelings(assignment.SelectedHirelingId)) { <option value="@hire.HirelingId">@hire.HirelingName</option> } </select> </td> <td class="p-3"> <p>@GetAssignmentLabel(assignment)</p> </td> </tr> } } } </table> @code { // 数据模型类(适配你的现有实体结构) public class Improvements { public int ImprovementId { get; set; } public string ImprovementHex { get; set; } public string ImprovementName { get; set; } public string ImprovementMaterial { get; set; } } public class MapHex { public string HexName { get; set; } } public class Hireling { public int HirelingId { get; set; } public string HirelingName { get; set; } } // 跟踪雇用人分配状态的模型 public class HirelingAssignment { public int ImprovementId { get; set; } public int? SelectedHirelingId { get; set; } } private List<Improvements> Improvment = ImprovementsRepository.GetImprovements(); private List<MapHex> HexName = MapHexRepository.GetMapHex(); private List<Hireling> Hirelings = HirelingRepository.GetHirelings(); private List<HirelingAssignment> Assignments = new(); protected override void OnInitialized() { // 为每个建筑初始化4个可分配位置 foreach (var imp in Improvment) { for (int i = 0; i < 4; i++) { Assignments.Add(new HirelingAssignment { ImprovementId = imp.ImprovementId }); } } } // 获取当前可用的雇用人(排除已分配的,保留当前选中项用于取消分配) private IEnumerable<Hireling> AvailableHirelings(int? currentSelectedId) { var assignedIds = Assignments.Where(a => a.SelectedHirelingId.HasValue && a.SelectedHirelingId != currentSelectedId) .Select(a => a.SelectedHirelingId.Value) .ToList(); return Hirelings.Where(h => !assignedIds.Contains(h.HirelingId)); } // 触发UI更新 private void UpdateAssignment(HirelingAssignment assignment) { StateHasChanged(); } // 生成标签显示文本 private string GetAssignmentLabel(HirelingAssignment assignment) { if (!assignment.SelectedHirelingId.HasValue) return "未分配雇用人"; var hireling = Hirelings.FirstOrDefault(h => h.HirelingId == assignment.SelectedHirelingId); return hireling != null ? $"已分配:{hireling.HirelingName}" : "未找到雇用人"; } }
关键改动说明
- 新增分配跟踪模型:用
HirelingAssignment类独立记录每个建筑位置的选中状态,避免直接修改原始业务数据。 - 初始化分配位置:在组件初始化时,为每个建筑生成4个可分配位置,确保每个下拉菜单有独立的绑定对象。
- 下拉菜单动态过滤:
AvailableHirelings方法自动排除已分配的雇用人,同时保留当前选中项,支持用户取消分配操作。 - 标签文本动态更新:
GetAssignmentLabel方法根据选中状态实时显示对应的雇用人名称或默认提示。 - UI同步更新:选中变化时调用
StateHasChanged()强制刷新所有下拉菜单,确保可用选项实时同步。
内容的提问来源于stack exchange,提问作者AirshipPirate
相关产品推荐
相关产品推荐

