如何基于ListViewItem中CompanyCode过滤Paycode_ComboBox选项
解决方案
方法一:通过CollectionViewSource在XAML中实现过滤
在DataTemplate内部定义CollectionViewSource,绑定全局Paycodes集合后,通过过滤事件根据当前列表项的选中公司筛选数据。
修改后的XAML片段
<ListView Name="PaycodeMapping_ListView" ItemsSource="{Binding Model.PaycodeMappings, NotifyOnSourceUpdated=True}"> <ListView.ItemTemplate> <DataTemplate> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="100"/> <ColumnDefinition Width="125"/> </Grid.ColumnDefinitions> <!-- Company Code --> <ComboBox Name="CompanyCode_ComboBox" Width="100" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0" ItemsSource="{Binding DataContext.CompanyList, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}" SelectedItem="{Binding Path=Company, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Grid.Row="0" Grid.Column="1"/> <!-- 定义过滤用的CollectionViewSource --> <CollectionViewSource x:Key="FilteredPaycodes" Source="{Binding DataContext.Paycodes, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}" Filter="FilteredPaycodes_Filter"/> <!-- Paycode ComboBox --> <ComboBox Name="Paycode_ComboBox" HorizontalAlignment="Left" Width="125" ItemsSource="{Binding Source={StaticResource FilteredPaycodes}}" DisplayMemberPath="CodeDesc" SelectedItem="{Binding Path=Paycode, NotifyOnSourceUpdated=True, Mode=TwoWay}" Grid.Row="0" Grid.Column="2" /> </Grid> </DataTemplate> </ListView.ItemTemplate> </ListView>
后台添加过滤逻辑(UserControl代码-behind)
private void FilteredPaycodes_Filter(object sender, FilterEventArgs e) { if (e.Item is Paycode paycode && sender is CollectionViewSource cvs) { // 获取当前列表项的DataContext(即PaycodeMapping对象) var mapping = ((FrameworkElement)cvs.Parent).DataContext as PaycodeMapping; e.Accepted = mapping?.Company != null && paycode.CompanyCode == mapping.Company.CompanyCode; } }
刷新过滤结果
在PaycodeMapping类的Company属性 setter 中添加刷新逻辑,确保切换公司时Paycode列表实时更新:
private Company _company; public Company Company { get => _company; set { if (_company != value) { _company = value; OnPropertyChanged(); // 找到当前项的CollectionView并刷新 var view = CollectionViewSource.GetDefaultView(FilteredPaycodes); view?.Refresh(); } } }
方法二:ViewModel层级实现过滤(MVVM友好)
在PaycodeMapping类中新增过滤后的Paycodes属性,当选中公司变化时自动筛选数据,完全避免后台代码介入。
修改PaycodeMapping类
public class PaycodeMapping : INotifyPropertyChanged { private readonly IEnumerable<Paycode> _allPaycodes; private Company _company; private IEnumerable<Paycode> _filteredPaycodes; // 构造时传入全局Paycodes集合 public PaycodeMapping(IEnumerable<Paycode> allPaycodes) { _allPaycodes = allPaycodes; FilterPaycodes(); } public Company Company { get => _company; set { if (_company != value) { _company = value; OnPropertyChanged(); FilterPaycodes(); } } } // 绑定给Paycode ComboBox的过滤后集合 public IEnumerable<Paycode> FilteredPaycodes { get => _filteredPaycodes; private set { _filteredPaycodes = value; OnPropertyChanged(); } } private void FilterPaycodes() { if (Company == null) { FilteredPaycodes = Enumerable.Empty<Paycode>(); return; } FilteredPaycodes = _allPaycodes.Where(p => p.CompanyCode == Company.CompanyCode).ToList(); } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
修改XAML绑定
将Paycode ComboBox的ItemsSource直接绑定到当前项的过滤后属性:
<!-- Paycode ComboBox --> <ComboBox Name="Paycode_ComboBox" HorizontalAlignment="Left" Width="125" ItemsSource="{Binding FilteredPaycodes}" DisplayMemberPath="CodeDesc" SelectedItem="{Binding Path=Paycode, NotifyOnSourceUpdated=True, Mode=TwoWay}" Grid.Row="0" Grid.Column="2" />
内容的提问来源于stack exchange,提问作者BrianKE
相关产品推荐
相关产品推荐

