MudBlazor Autocomplete自定义分组渲染及禁用分组项实现问询
在MudBlazor Autocomplete中实现国家分组的城市选择(带禁用分组标题)
需求回顾
- 数据源是字典结构:键为国家名,值为对应城市列表(比如
Country1下有City1、City2,Country2下有City1、City4) - 搜索城市时,展示所有包含该城市的国家分组,每个分组下只显示匹配的城市
- 国家作为独立的分组标题,不可选中(禁用状态)
实现步骤
1. 统一数据源格式
MudAutocomplete需要处理扁平的条目列表,先把字典转成带分组标识的条目集合,方便后续区分分组头和城市项:
// 自定义类区分分组头和城市 public class CityGroupItem { public string Text { get; set; } public bool IsGroupHeader { get; set; } public string Country { get; set; } // 关联所属国家,用于搜索匹配 } // 初始化原始数据源 private Dictionary<string, List<string>> _countryCities = new() { { "Country1", new List<string> { "City1", "City2" } }, { "Country2", new List<string> { "City1", "City4" } } }; private List<CityGroupItem> _groupedItems = new(); protected override void OnInitialized() { // 把字典拆成分组头+城市的扁平列表 foreach (var country in _countryCities) { _groupedItems.Add(new CityGroupItem { Text = country.Key, IsGroupHeader = true, Country = country.Key }); foreach (var city in country.Value) { _groupedItems.Add(new CityGroupItem { Text = city, IsGroupHeader = false, Country = country.Key }); } } }
2. 配置MudAutocomplete组件
核心配置搜索过滤逻辑、条目渲染、禁用判断三个部分:
<MudAutocomplete T="CityGroupItem" Label="选择城市" @bind-Value="_selectedCity" Items="_filteredItems" SearchFunc="@SearchCities" ItemTemplate="@RenderItem" ItemDisabledFunc="@IsItemDisabled" NoResultsText="未找到匹配城市"> </MudAutocomplete> @code { private CityGroupItem _selectedCity; private List<CityGroupItem> _filteredItems = new(); // 搜索逻辑:只保留包含匹配城市的国家分组和对应城市 private Task<List<CityGroupItem>> SearchCities(string searchText) { if (string.IsNullOrWhiteSpace(searchText)) { _filteredItems = _groupedItems.ToList(); return Task.FromResult(_filteredItems); } // 先找出所有有匹配城市的国家 var matchedCountries = _countryCities .Where(kv => kv.Value.Any(city => city.Contains(searchText, StringComparison.OrdinalIgnoreCase))) .Select(kv => kv.Key) .ToList(); // 筛选出这些国家的分组头,以及对应国家下的匹配城市 _filteredItems = _groupedItems .Where(item => (item.IsGroupHeader && matchedCountries.Contains(item.Country)) || (!item.IsGroupHeader && matchedCountries.Contains(item.Country) && item.Text.Contains(searchText, StringComparison.OrdinalIgnoreCase)) ) .ToList(); return Task.FromResult(_filteredItems); } // 自定义条目渲染:分组头加粗加浅背景,城市正常显示 private RenderFragment<CityGroupItem> RenderItem = item => __builder => { if (item.IsGroupHeader) { <MudListItem Disabled="true" Class="font-weight-bold bg-light">@item.Text</MudListItem> } else { <MudListItem>@item.Text</MudListItem> } }; // 禁用分组头,只允许选中城市 private bool IsItemDisabled(CityGroupItem item) { return item.IsGroupHeader; } }
3. 可选:样式优化
给分组头加侧边标识,视觉区分更明显:
.mud-list-item.font-weight-bold.bg-light { padding-left: 0.5rem; border-left: 3px solid var(--mud-palette-primary); }
关键细节说明
- 搜索过滤:先定位有匹配城市的国家,再过滤条目,避免出现孤立的分组头或无关城市
- 禁用逻辑:通过
ItemDisabledFunc直接标记分组头为禁用,同时在渲染时给分组头加特殊样式,用户一眼就能区分 - 选中逻辑:只有城市项能被选中,完全符合需求里的交互要求
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

