2013-06-30 46 views
5

ObservableCollectionをタイプ(AddPoint型)に基づいてサブセットにフィルタリングし、重複なしで昇順に欲しいです。私の基本クラスはModelBase、サブクラスAddPoint、Time、Repeatなどです... ObservableCollection MotionSequenceCollectionはこれらの型で任意の順序で塗りつぶされ、重複するものもあります。WPFバインディングフィルタリングObservableCollection ICollectionView to Combobox

私はいくつかの異なる時間を試して、私が '引っ張った' ICollectionViewプロパティに以下のように表示しました:Bind subset of collection。種類別

監視可能なコレクション

private ObservableCollection<ModelBase> _motionSequenceCollection = 
     new ObservableCollection<ModelBase>(); 

    public ObservableCollection<ModelBase> MotionSequenceCollection 
    { 
     get 
     { 
      return _motionSequenceCollection; 
     } 

     set 
     { 
      if (_motionSequenceCollection == value) 
      { 
       return; 
      } 

      var oldValue = _motionSequenceCollection; 
      _motionSequenceCollection = value; 

      // Update bindings, no broadcast 
      RaisePropertyChanged(); 
     } 
    } 

    public ICollectionView Location 
    { 
     get 
     { 
      var location = CollectionViewSource.GetDefaultView(_motionSequenceCollection); 

      //DOES NOT WORK. PROBLEM: GetType() creates type of system.type() and AddPoint, which don't work. Need a cast, or something?? 
      // found at https://stackoverflow.com/questions/9621393/bind-subset-of-collection The problem is that there is an error: 
      // Cannot apply operator '==' to operands of type 'System.Type' and 'MotionSeq.Model.AddPoint', 
      // candidates are: 
      //   bool ==(System.Reflection.MemberInfo, System.Reflection.memberInfo) (in class MemberInfo) 
      //   bool ==(System.type, System.Type) (in class Type) 
      //location.Filter = p => (p as ModelBase).GetType() == AddPoint; 

      //DOES NOT WORK. PROBLEM: Affects the main collection and won't let TIME type added. 
      //location.Filter = o1 => (o1 is AddPoint); 

      //DOES NOT WORK. PROBLEM: Sorts fine, but also sorts MotionSequenceCollection!! What up w/ that!? 
      //location.SortDescriptions.Add(new SortDescription("AddPointClassName", ListSortDirection.Ascending)); 

      //DOES NOT WORK. PROBLEM: MotionSequenceCollection does not update. 
      //location.Filter = p => (p as ModelBase) == AddPoint; 

      //DOES NOT WORK. PROBLEM: Source is not instantiated(?) and exmaple from stackoverflow and not sure how that got there in the first place. 
      //source.Filter = p => (p as ModelBase).GetType() == "AddPoint"; 
      //return source; 

      return location; 
     } 
    } 

答えて

2

すべてのコレクションにはデフォルトのCollectionViewがあります。 WPFは常にコレクションではなくビューにバインドされます。コレクションに直接バインドすると、WPFは実際にそのコレクションの既定のビューにバインドされます。このデフォルトビューはコレクションへのすべてのバインディングによって共有されます。これにより、コレクションへのすべての直接バインディングは、1つのデフォルトビューのソート、フィルタ、グループ、および現在のアイテム特性を共有します。

CollectionViewSourceを作成し、このようにそのフィルタリングロジックを設定してみてください:

//create it as static resource and bind your ItemsControl to it 
<CollectionViewSource x:Key="csv" Source="{StaticResource MotionSequenceCollection}" 
        Filter="CollectionViewSource_Filter"> 
    <CollectionViewSource.GroupDescriptions> 
     <PropertyGroupDescription PropertyName="YYY"/> 
    </CollectionViewSource.GroupDescriptions> 
    <CollectionViewSource.SortDescriptions> 
     <scm:SortDescription PropertyName="YYY" Direction="Ascending"/> 
    </CollectionViewSource.SortDescriptions> 
</CollectionViewSource> 

private void CollectionViewSource_Filter(object sender, FilterEventArgs e) 
{ 
    var t = e.Item as ModelBase; 
    if (t != null) 

    { 
     //use your filtering logic here 

    } 
} 
+0

正直なところ、私はこれで大量に苦労しています。私はもともとCollectionViewSource_FIlterを使って@ makcの方法に行きましたが、いくつかの例がありましたが、問題はリストを区別することでした - それは2日前であり、頭が曇っています。フィルタは次のようなものです: – FloppyDisk

+0

私のコメントを修正する必要があります。私はあなたのソリューションを働かせて、collectionviewsourceについて多くのことを学びました。問題は、重複があり、コンボボックス(フィルタリングされたビュー)に1つしか表示されない場合、コレクション内で編集すると、編集されたレコード。唯一のものがあれば、それはpropertychangedの後で期待通りに更新されます。だから私は後にlinqのパスを下ったが、それは悲惨であることが判明している。 – FloppyDisk

+0

@FloppyDisk私はあなたがちょうど過去のコピーをしなかったことを非常にうれしく思っていますが、読んで学びました:)私は問題を完全に理解しているとは確信していません。小さなスタンドアロンの例を作成してみてください。 – makc

1

フィルタリングが容易です。これはうまくいくはずです:

location.Filter = p => p.GetType() == typeof(AddPoint); 

並べ替えも非常に簡単です。 IComparerを実装し、それをコレクションビューのCustomSortプロパティに割り当てるだけです。

重複を削除する簡単な方法はありませんtho(私は認識していない)。他の場所でやることをお勧めします。たとえば、基になるコレクションを区別することができます。

+0

私はタックを変更し、LINQでのObservableCollectionのサブセットを作成しようとしました。その後、それを私の見解に結びつけてください。それは真剣に走っています。 IComparerを実装する必要があるというエラーがあります。それを見てください。応答していただきありがとうございます。 – FloppyDisk