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
相关产品推荐
相关产品推荐

