You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:54:57