如何在使用 collection 查看源代码的 wpf 中与 collection 内的 collection 绑定时应用过滤器

How to apply filter when binding with collection inside collection in wpf using collection view source

我有一个 ListBox,其扩展器与 ListBoxItem 不同。 expander 的内容中有 ListBox。现在我想在 header 和扩展器的内容中应用搜索过滤器。

例如:-

如果 header 有 a 并且内容有 b、c、d、bt,如果我搜索 b 那么将显示具有 a 的扩展器,而内部内容只显示 b 和 bt。

下面是我的绑定结构。

private ObservableCollection<FontDetail> _fontDetail;
public ObservableCollection<FontDetail> FontDetailList
{
    get
    {
        return _fontDetail;
    }
}

    FontDetail
    {
        public FamilyChild fontChild { get; set; }
        //ContextMenu End

        public bool IsFamily { get; set; }
        public int TotalFonts { get; set; }
        public List<FamilyChild> FamilyChildList { get; set; }
    }

    public class FamilyChild
    {
        public FontStatus Status { get; set; }


        public long TimeToAdd { get; set; }
        public FontType FontType { get; set; }
        public string SampleText { get; set; }
        public string Name { get; set; }
        public string FontFamily { get; set; }
        public string FontStyle { get; set; }
        public long FontWeight { get; set; }
        public string FontId { get; set; }

        public string MenuItem1 { get; set; }
        public string MenuItem2 { get; set; }
        public string MenuItem3 { get; set; }

        public bool IsEnableMenuItem1 { get; set; }
        public bool IsEnableMenuItem2 { get; set; }
        public bool IsEnableMenuItem3 { get; set; }
    }

所以我已经绑定了 ListBox 和 FontDetailList。现在我想在 FontDetail 和 FamilyChildList 上应用过滤器。 FontDetail 绑定在 Expander header 中,FamilyChildList 绑定为 expander 的内容。

您必须应用过滤器两次。首先针对外部集合,然后在外部集合的过滤器谓词中应用第二个过滤器。下面代码过滤车辆名称以"S"开头的员工,并显示员工姓名和车辆列表。

DataStore 包含 EmployeeList, Employee 包含 VehicleList

        private void BtnFilter_Click(object sender, RoutedEventArgs e)
        {
            var source = CollectionViewSource.GetDefaultView(Dgrd.ItemsSource);            
            source.Filter = new Predicate<object>(FilterEmployees);            

            source.Refresh();
        }

        private bool FilterEmployees(object o)
        {
            DB1.Employee e = o as DB1.Employee;

            var vehicles = CollectionViewSource.GetDefaultView(e.Vehicles);
            vehicles.Filter = new Predicate<object>(FilterVehicles);

            return (e.Vehicles.Where(v=>v.Name.StartsWith("S"))).Count() > 0;
        }

        private bool FilterVehicles(object obj)
        {
            DB1.Vehicle v = obj as DB1.Vehicle;
            return v.Name.StartsWith("S");
        }