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

如何在WinUI 3的DataGrid中创建可搜索/筛选的Combobox

WinUI 3 DataGrid 带搜索功能的下拉单元格实现方案

核心思路

放弃原生DataGridComboBoxColumn,改用DataGridTemplateColumn自定义单元格模板,嵌入带搜索能力的下拉控件(可基于AutoSuggestBox封装或直接使用),同时完成与DataGrid数据源的双向绑定。

实现步骤

1. 封装可搜索的下拉控件

先做一个复用性强的搜索下拉控件,利用AutoSuggestBox实现实时搜索过滤:

<UserControl x:Class="YourProjectNamespace.SearchableDropDown"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <AutoSuggestBox x:Name="SearchBox"
                        PlaceholderText="输入关键词搜索..."
                        TextChanged="SearchBox_TextChanged"
                        SuggestionChosen="SearchBox_SuggestionChosen"/>
    </Grid>
</UserControl>

后台代码处理搜索逻辑与绑定:

public sealed partial class SearchableDropDown : UserControl
{
    // 下拉选项集合依赖属性
    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register(nameof(ItemsSource), typeof(IEnumerable), typeof(SearchableDropDown), new PropertyMetadata(null, OnItemsSourceChanged));

    // 选中项依赖属性
    public static readonly DependencyProperty SelectedItemProperty =
        DependencyProperty.Register(nameof(SelectedItem), typeof(object), typeof(SearchableDropDown), new PropertyMetadata(null));

    public IEnumerable ItemsSource
    {
        get => (IEnumerable)GetValue(ItemsSourceProperty);
        set => SetValue(ItemsSourceProperty, value);
    }

    public object SelectedItem
    {
        get => GetValue(SelectedItemProperty);
        set => SetValue(SelectedItemProperty, value);
    }

    public SearchableDropDown()
    {
        this.InitializeComponent();
    }

    private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is SearchableDropDown control && e.NewValue is IEnumerable items)
        {
            control.SearchBox.ItemsSource = items;
        }
    }

    private void SearchBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
    {
        // 仅在用户输入时触发过滤
        if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput && ItemsSource != null)
        {
            var keyword = sender.Text.ToLower();
            sender.ItemsSource = ItemsSource.Cast<object>()
                .Where(item => item.ToString().ToLower().Contains(keyword))
                .ToList();
        }
    }

    private void SearchBox_SuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
    {
        SelectedItem = args.SelectedItem;
        sender.Text = args.SelectedItem.ToString();
    }
}

2. 在DataGrid中配置自定义列

将自定义搜索下拉控件嵌入DataGridTemplateColumn,区分显示模板和编辑模板:

<DataGrid x:Name="TargetDataGrid"
          ItemsSource="{Binding YourDataList}"
          AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="带搜索的下拉列">
            <!-- 非编辑状态显示文本 -->
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding TargetProperty}"
                               VerticalAlignment="Center"
                               Margin="4"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <!-- 编辑状态显示搜索下拉 -->
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <local:SearchableDropDown ItemsSource="{Binding DataContext.DropDownOptions, ElementName=TargetDataGrid}"
                                             SelectedItem="{Binding TargetProperty, Mode=TwoWay}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

3. 关键绑定说明

  • ItemsSource通过ElementName绑定到DataGrid上下文里的下拉选项集合,确保所有单元格共享同一数据源
  • SelectedItem双向绑定到DataGrid每行数据的对应属性,实现选中值与数据源的同步
  • 非编辑状态用TextBlock展示当前值,避免编辑控件一直显示影响性能

简易替代方案(无需自定义控件)

如果不需要复用控件,可直接在编辑模板里用AutoSuggestBox快速实现:

<DataGridTemplateColumn Header="带搜索的列">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding TargetProperty}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <AutoSuggestBox ItemsSource="{Binding DataContext.DropDownOptions, ElementName=TargetDataGrid}"
                            Text="{Binding TargetProperty, Mode=TwoWay}"
                            SuggestionChosen="AutoSuggestBox_SuggestionChosen"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

后台补充选中逻辑:

private void AutoSuggestBox_SuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
{
    var dataItem = sender.DataContext as YourDataModel;
    if (dataItem != null)
    {
        dataItem.TargetProperty = args.SelectedItem.ToString();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 15:55:18