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

WPF C#中实现DataGrid内ComboBox的级联过滤功能

WPF DataGrid 三级ComboBox级联过滤实现

1. ViewModel核心逻辑实现

假设ViewModel已继承INotifyPropertyChanged,核心逻辑通过选中属性的setter触发数据过滤与清空操作:

public class MainViewModel : INotifyPropertyChanged
{
    private readonly ILocationDal _locationDal;

    // 全量国家数据(页面加载时从DAL获取)
    public ObservableCollection<Country> Countries { get; set; }
    // 过滤后的省份数据
    public ObservableCollection<Province> Provinces { get; set; }
    // 过滤后的地区数据
    public ObservableCollection<District> Districts { get; set; }

    private Country _selectedCountry;
    public Country SelectedCountry
    {
        get => _selectedCountry;
        set
        {
            _selectedCountry = value;
            OnPropertyChanged(nameof(SelectedCountry));
            
            // 切换国家时清空省份、地区选中值
            SelectedProvince = null;
            SelectedDistrict = null;
            
            // 加载当前国家对应的省份
            Provinces.Clear();
            if (_selectedCountry != null)
            {
                foreach (var province in _locationDal.GetProvincesByCountryId(_selectedCountry.Id))
                {
                    Provinces.Add(province);
                }
            }
        }
    }

    private Province _selectedProvince;
    public Province SelectedProvince
    {
        get => _selectedProvince;
        set
        {
            _selectedProvince = value;
            OnPropertyChanged(nameof(SelectedProvince));
            
            // 切换省份时清空地区选中值
            SelectedDistrict = null;
            
            // 加载当前省份对应的地区
            Districts.Clear();
            if (_selectedProvince != null)
            {
                foreach (var district in _locationDal.GetDistrictsByProvinceId(_selectedProvince.Id))
                {
                    Districts.Add(district);
                }
            }
        }
    }

    private District _selectedDistrict;
    public District SelectedDistrict
    {
        get => _selectedDistrict;
        set
        {
            _selectedDistrict = value;
            OnPropertyChanged(nameof(SelectedDistrict));
        }
    }

    public MainViewModel(ILocationDal locationDal)
    {
        _locationDal = locationDal;
        Countries = new ObservableCollection<Country>(_locationDal.GetAllCountries());
        Provinces = new ObservableCollection<Province>();
        Districts = new ObservableCollection<District>();
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

2. DataGrid的XAML配置

通过RelativeSource绑定到ViewModel的集合与选中属性,确保行内ComboBox能正确获取数据:

<DataGrid x:Name="LocationGrid" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <!-- 国家ComboBox列 -->
        <DataGridTemplateColumn Header="国家">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding DataContext.Countries, RelativeSource={RelativeSource AncestorType=DataGrid}}"
                              SelectedItem="{Binding DataContext.SelectedCountry, RelativeSource={RelativeSource AncestorType=DataGrid}}"
                              DisplayMemberPath="Name"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

        <!-- 省份ComboBox列 -->
        <DataGridTemplateColumn Header="省份">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding DataContext.Provinces, RelativeSource={RelativeSource AncestorType=DataGrid}}"
                              SelectedItem="{Binding DataContext.SelectedProvince, RelativeSource={RelativeSource AncestorType=DataGrid}}"
                              DisplayMemberPath="Name"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

        <!-- 地区ComboBox列 -->
        <DataGridTemplateColumn Header="地区">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding DataContext.Districts, RelativeSource={RelativeSource AncestorType=DataGrid}}"
                              SelectedItem="{Binding DataContext.SelectedDistrict, RelativeSource={RelativeSource AncestorType=DataGrid}}"
                              DisplayMemberPath="Name"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

3. DAL层方法补充

确保数据访问层实现以下基础数据查询方法:

  • List<Country> GetAllCountries():获取全量国家数据
  • List<Province> GetProvincesByCountryId(int countryId):根据国家ID筛选省份
  • List<District> GetDistrictsByProvinceId(int provinceId):根据省份ID筛选地区

示例实现:

public class LocationDal : ILocationDal
{
    private readonly YourDbContext _dbContext;

    public LocationDal(YourDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public List<Country> GetAllCountries()
    {
        return _dbContext.Countries.ToList();
    }

    public List<Province> GetProvincesByCountryId(int countryId)
    {
        return _dbContext.Provinces.Where(p => p.CountryId == countryId).ToList();
    }

    public List<District> GetDistrictsByProvinceId(int provinceId)
    {
        return _dbContext.Districts.Where(d => d.ProvinceId == provinceId).ToList();
    }
}

4. 窗口ViewModel初始化

在窗口构造函数中完成ViewModel的实例化与绑定:

public MainWindow()
{
    InitializeComponent();
    var dal = new LocationDal(new YourDbContext());
    DataContext = new MainViewModel(dal);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 18:43:19