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

WPF DataGrid实现可编辑带输入过滤的Combobox列开发咨询

问题解决方案

可过滤DataGrid ComboBox列实现方案

首先先修正你现有代码的基础问题:

  1. MainWindowViewModel未实现INotifyPropertyChanged接口,属性变更无法通知界面同步更新
  2. DataGridComboBoxColumn的TextBinding错误绑定到了BindingGroupName,实际应该绑定Item的Name属性
  3. ItemsList用了ObservableCollection<object>,存在无意义的装箱操作,应该改为具体的ObservableCollection<Item>类型

原生WPF实现过滤功能步骤

步骤1:修改ViewModel层

使用WPF内置的ICollectionView实现集合过滤,不需要额外引入第三方依赖:

using System.Windows.Data;
using System.ComponentModel;
using System.Runtime.CompilerServices;

public class MainWindowViewModel : INotifyPropertyChanged
{
    private Customer _objCustomer;
    private string _currentSearchText;

    public Customer ObjCustomer
    {
        get => _objCustomer;
        set
        {
            _objCustomer = value;
            OnPropertyRaised();
        }
    }
    
    // 全量商品集合
    public ObservableCollection<Item> AllItems { get; set; }
    // 带过滤的视图集合,绑定到ComboBox
    public ICollectionView FilteredItems { get; set; }
    
    // 搜索文本,输入时触发过滤刷新
    public string CurrentSearchText
    {
        get => _currentSearchText;
        set
        {
            _currentSearchText = value;
            OnPropertyRaised();
            FilteredItems.Refresh();
        }
    }

    public MainWindowViewModel()
    {
        ObjCustomer = new Customer();
        ObjCustomer.Items = LoadCustomerItems();
        AllItems = LoadAvailableItems();
        // 初始化集合过滤视图
        FilteredItems = CollectionViewSource.GetDefaultView(AllItems);
        FilteredItems.Filter = ItemFilterRule;
    }

    // 过滤规则,可自行加入重复商品排除逻辑
    private bool ItemFilterRule(object obj)
    {
        if (obj is not Item item) return false;
        if (string.IsNullOrWhiteSpace(CurrentSearchText)) return true;
        // 不区分大小写前缀匹配
        return item.Name.StartsWith(CurrentSearchText, StringComparison.OrdinalIgnoreCase);
    }

    private ObservableCollection<Item> LoadAvailableItems()
    {
        return new ObservableCollection<Item>
        {
            new Item { Name = "Apple" },
            new Item { Name = "Peach" },
            new Item { Name = "Mango" },
            new Item { Name = "Banana" },
            new Item { Name = "Toilet paper" },
            new Item { Name = "Iphone" },
            new Item { Name = "Water" }
        };
    }
    
    private ObservableCollection<Item> LoadCustomerItems()
    {
        return new ObservableCollection<Item>
        {
            new Item { Name = "Apple", Quantity = 1 },
            new Item { Name = "Banana", Quantity = 2 },
            new Item { Name = "Peach", Quantity = 3 }
        };
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyRaised([CallerMemberName] string propertyname = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyname));
    }
}

步骤2:修改XAML代码

用DataGridTemplateColumn替代原生的DataGridComboBoxColumn,实现可编辑、带输入过滤的下拉框:

<DataGrid HorizontalAlignment="Left" 
          Height="374" 
          Margin="37,31,0,64" 
          VerticalAlignment="Center" 
          Width="391"
          ItemsSource="{Binding ObjCustomer.Items,Source={StaticResource viewModel}}"
          AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="商品">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <ComboBox IsEditable="True"
                              IsTextSearchEnabled="False"
                              ItemsSource="{Binding FilteredItems, Source={StaticResource viewModel}}"
                              Text="{Binding DataContext.CurrentSearchText, Source={StaticResource viewModel}, UpdateSourceTrigger=PropertyChanged}"
                              SelectedItem="{Binding ., Mode=TwoWay}"
                              DisplayMemberPath="Name"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn Header="数量"
                            Binding="{Binding Quantity, Mode=TwoWay}"/>
    </DataGrid.Columns>
</DataGrid>

控件框架选择建议

  • 学习阶段优先使用原生WPF功能:先搞懂绑定、集合视图、模板、路由事件这些核心机制,再使用第三方控件,否则出现问题你根本找不到排查方向。
  • 商业开发/赶进度直接用Syncfusion、DevExpress这类成熟控件库:这类库已经封装了绝大多数常用业务功能,比如下拉框过滤、表格校验、数据导出、主题适配,能节省70%以上的UI开发时间,稳定性也远高于自己手写的实现。

额外开发建议

  1. 你现在的Customer和Item类的属性Set方法都没有调用OnPropertyRaised,后续修改属性值界面不会自动更新,记得补上调用逻辑。
  2. 推荐使用CommunityToolkit.Mvvm库,不用自己手写INotifyPropertyChanged的样板代码,由源生成器自动生成,能大幅减少低级错误。
  3. 重复商品校验可以直接加到ItemFilterRule方法里,把当前客户已经选过的商品过滤掉,即可避免重复选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 19:18:02