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

.NET MAUI中是否有类似HTML Datalist的搜索过滤选择控件?

.NET MAUI 实现类似HTML Datalist的搜索式选择控件方案

.NET MAUI没有原生的直接等效HTML Datalist的控件,但可以通过Entry + CollectionView组合自定义实现,完全免费且可控。下面针对你遇到的三个问题给出具体解决方法:

一、从数据库预填已有数据

在页面初始化阶段读取数据库数据,绑定到ViewModel的集合中即可。假设你的数据模型为Item,包含Id和Name字段:

// 数据模型
public class Item
{
    public int Id { get; set; }
    public string Name { get; set; }
}

// 页面ViewModel(基于MVVM模式)
public class MyPageViewModel : INotifyPropertyChanged
{
    // 存储全量数据
    public ObservableCollection<Item> AllItems { get; set; } = new();
    // 存储过滤后的数据
    public ObservableCollection<Item> FilteredItems { get; set; } = new();
    // 搜索框绑定文本
    private string _searchText;
    public string SearchText
    {
        get => _searchText;
        set
        {
            _searchText = value;
            FilterItems();
            OnPropertyChanged();
        }
    }
    // 控制列表显示/隐藏
    private bool _isListVisible;
    public bool IsListVisible
    {
        get => _isListVisible;
        set
        {
            _isListVisible = value;
            OnPropertyChanged();
        }
    }
    // 选中的项(可选)
    private Item _selectedItem;
    public Item SelectedItem
    {
        get => _selectedItem;
        set
        {
            _selectedItem = value;
            OnPropertyChanged();
        }
    }

    // 从数据库加载全量数据
    public async Task LoadItemsFromDb()
    {
        // 替换为你的数据库查询逻辑
        var dbItems = await YourDatabaseService.GetAllItemsAsync();
        AllItems.Clear();
        foreach (var item in dbItems)
        {
            AllItems.Add(item);
        }
    }

    // 过滤逻辑
    private void FilterItems()
    {
        FilteredItems.Clear();
        // 搜索框为空时不加载任何数据
        if (string.IsNullOrWhiteSpace(SearchText))
        {
            IsListVisible = false;
            return;
        }
        // 按名称模糊匹配(忽略大小写)
        var matchedItems = AllItems.Where(item => 
            item.Name.IndexOf(SearchText, StringComparison.OrdinalIgnoreCase) >= 0);
        foreach (var item in matchedItems)
        {
            FilteredItems.Add(item);
        }
        // 有匹配结果才显示列表
        IsListVisible = FilteredItems.Count > 0;
    }

    // 选中项命令
    public ICommand SelectItemCommand => new Command<Item>(item =>
    {
        if (item == null) return;
        SelectedItem = item;
        SearchText = item.Name; // 将选中项显示在搜索框
        IsListVisible = false; // 选中后隐藏列表
    });

    // 实现INotifyPropertyChanged接口
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

二、解决输入时过滤列表空白的问题

空白问题通常出在绑定逻辑或数据集合类型上,确保:

  • 使用ObservableCollection作为集合类型,数据变更自动通知UI
  • 过滤方法正确遍历全量数据,避免线程异常
  • XAML中绑定路径完全匹配ViewModel属性

对应的XAML代码:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vm="clr-namespace:YourApp.ViewModels"
             xmlns:models="clr-namespace:YourApp.Models"
             x:Class="YourApp.Pages.MyPage"
             x:DataType="vm:MyPageViewModel">
    <VerticalStackLayout Padding="10">
        <!-- 搜索输入框 -->
        <Entry Text="{Binding SearchText, Mode=TwoWay}"
               Placeholder="搜索选项..."
               Focused="Entry_Focused"
               Unfocused="Entry_Unfocused"/>
        
        <!-- 过滤结果列表 -->
        <CollectionView ItemsSource="{Binding FilteredItems}"
                        IsVisible="{Binding IsListVisible}"
                        HeightRequest="200"
                        Margin="0,5,0,0">
            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="models:Item">
                    <Label Text="{Binding Name}"
                           Padding="12"
                           FontSize="16"
                           BackgroundColor="{OnPlatform Android=#F5F5F5, iOS=#F5F5F5}">
                        <Label.GestureRecognizers>
                            <TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type vm:MyPageViewModel}}, Path=SelectItemCommand}"
                                                  CommandParameter="{Binding .}"/>
                        </Label.GestureRecognizers>
                    </Label>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </VerticalStackLayout>
</ContentPage>

页面后台代码处理焦点事件:

public partial class MyPage : ContentPage
{
    private MyPageViewModel _viewModel;

    public MyPage(MyPageViewModel viewModel)
    {
        InitializeComponent();
        _viewModel = viewModel;
        BindingContext = viewModel;
    }

    protected override async void OnAppearing()
    {
        base.OnAppearing();
        // 页面显示时加载数据库数据
        await _viewModel.LoadItemsFromDb();
    }

    private void Entry_Focused(object sender, FocusEventArgs e)
    {
        // 获得焦点时,仅当搜索框有内容才显示列表
        if (!string.IsNullOrWhiteSpace(_viewModel.SearchText))
        {
            _viewModel.IsListVisible = true;
        }
    }

    private void Entry_Unfocused(object sender, FocusEventArgs e)
    {
        // 失去焦点时强制隐藏列表
        _viewModel.IsListVisible = false;
    }
}

三、解决搜索框为空/失去焦点时显示全量列表的问题

通过两个逻辑彻底控制列表显示:

  1. 在FilterItems方法中,搜索框为空时直接清空过滤集合并隐藏列表
  2. 监听输入框Unfocused事件,失去焦点时强制隐藏列表
  3. 输入框获得焦点时,仅当已有搜索内容才显示过滤结果,而非全量数据

内容的提问来源于stack exchange,提问作者BryanCass

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 19:25:41