2012-02-17 46 views
1

WPF/Observable Collectionを初めて使用しています。 Observable CollectionであるリストにPopulating TreeViewを使用しています。ObservableCollectionにバインドされたフィルタTreeView

私は私のツリーをフィルタリングしようとしています。ルートノード/親が条件に合格せず、子ノードが満足しても、私は親ノードをフィルタリングできません。

子ノードは基準を満たしているため、子ノードのツリーパス全体で表示されます。

Root 
    Animal 
    Dog 
    Cat 
    Fish 
    Fresh Water 
    Salt Water 

"水"を検索すると、Root-Fish-Fresh Water-Salt Waterが表示されます。

答えて

0

これまでのところ、私が見つけた最も優れたフィルタリングとソートは、CollectionViewとCollectionViewSourceのデュオです。

私はここでそれらを使用する方法の詳細に入るポストを持っている: WPF ListBoxItem Visibility and ScrollBar

基本的に何をやっていることはCollectionViewSource内のコレクションをホストしている、と伝えたときにビュー・オブジェクトにフィルタとソートの定義を追加していますItemsControl(ListBox、ListView、TreeView)は、表示するアイテムとそれらを表示する順序を示します。この方法では、コレクションを変更したり、複数のコレクションにわたって個々のアイテムを操作したりすることはありません。

すべてのビジネスオブジェクトクラスがViewModelsでホストされています。 ViewModelには、そのViewModelのクラスの型のMyRecordというプロパティがあります(この方法では、後で、どのViewModelTypeに関係なく、そのメソッドを呼び出すことができます)。

私が思い出したように、フィルタ方法は次のようになりました。

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メソッドが呼び出されたときにそのプロパティが設定されていました。

これはあなたが探していた機能ではない可能性がありますが、現時点では私が持っているものです

+0

あなたの答えをありがとうございます。しかし、これは私のために働いていないようです:(それは階層的なデータのために働くかどうかは分かりませんが、ルートレベルでフィルタを適用します。何か間違っています。私が私の例で示したTree View - Hierarchicalデータでこれをテストしたかどうかを確認したかっただけです。 – nmgans

+0

上記の例では、Searchは "Animal"と "Fish"子要素に適用されます。 "d"と入力すると、 "d"以降は何も返されず、 "Animal"または "Fish"にはありません。 Dogは "d"を持っているので、Animal - > Dogが表示されるようにしました。ツリーのすべてのレベルでどのようにフィルタを適用するのか教えてください。 – nmgans

+0

フィルタロジックメソッドでは、子オブジェクトがフィルタに一致するかどうかを確認するための方法が必要になります。私はあなたのために投稿したいと思っている例を見つけることができません。その中で、階層の各クラスにインスタンスメソッドがあり、それは文字列を受け取り、一致するフィルタに対してboolを返しました。その後、私のフィルタロジックでは、ツリーの下を歩き回ってアイテムを戻し、その値をトップレベルにバブリングするブロックを作成しました。 (それを考えてみると、私はまた、私は=フィルタに一致するように設定する拡張のためのクラスViewModelsのプロパティを持っていた...) – CodeWarrior

関連する問題