过滤TreeView绑定到ObservableCollection

时间:2012-02-17 20:03:34

标签: wpf treeview observablecollection

我是WPF / Observable Collection的新手。 我们使用Populating TreeView和Observable Collection列表。

我正在尝试过滤我的树,即使根节点/父节点符合条件且子节点满足,我也无法过滤父节点。

由于子节点满足条件,因此应该显示子节点的整个树路径。

Root
  Animal
     Dog
     Cat
  Fish
     Fresh Water
     Salt Water

当您搜索“水”时,它应显示Root-- Fish-Fresh-Water-Salt Water。

1 个答案:

答案 0 :(得分:-1)

到目前为止,我发现的最好的开箱即用过滤和排序是CollectionView和CollectionViewSource二重奏。

我有一篇帖子详细介绍了如何在这里使用它们: WPF ListBoxItem Visibility and ScrollBar

基本上你正在做的是在CollectionViewSource中托管集合,并在告诉ItemsControl(ListBox,ListView,TreeView)中显示要显示的项目和显示它们的顺序时,将View和Sort定义添加到Viewobject。通过这种方式,您不会更改集合,也不会在多个集合中操作单个项目。

实施例

我的所有业务对象类都托管在ViewModels中。 ViewModel每个都有一个名为MyRecord的属性,该属性是该ViewModel的类的类型(以后我可以调用该方法,无论我正在处理哪个ViewModelType,yay Late Binding!)

无论如何,我记得,我的过滤方法看起来像这样:

    private bool FilterByString(string filterString)
    {
        foreach (CustomerViewModel custVM in cvs.Source)
        {
            FilterChild(filterString, custVM);
            if (custVM.MatchesFilter(filterString))
            {
                return true;
            }
            else
            {
                return false;
            }

        }
    }

    private bool FilterChild(string filterString, Object parent)
    {
        bool match = false;
        if (parent.MyChildren != null && parent.MyChildren.Count > 0)
        {
            foreach (Object Child in parent.MyChildren)
            {
                //If any of the children return true, then this method returns true.
                //if all children return false, this method returns false.
                bool innerMatch = Child.MatchesFilter(filterString);
                match = (match == false ? innerMatch : match);
                Child.MatchesFilter(filterString);
                FilterChild(filterString, Child);
            }

        }
        bool outerMatch = parent.MatchesFilter;
        if (outerMatch || match)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

现在我记得了。我实际上并没有过滤孩子,我只是让他们崩溃了。我在ViewModel上设置属性的每个项目上都有扩展属性,并且在调用MatchesFilter方法时设置了该属性。仅过滤了顶级项目(仅当其下的每个项目与过滤器不匹配时才会过滤。

这可能不是您正在寻找的功能,但目前,它就是我拥有的功能。