2011-02-07 5 views
8

私はwpf-mvvmアプリケーションを持っています。xamlからコレクションをフィルタリングできますか?

私は私のviewmodelで観察可能なコレクションを持っている

public ObservableCollection<BatchImportResultMessageDto> ImportMessageList { get; set; } 

"BatchImportResultMessageDto" は、2つのプロパティ..

結果type..andメッセージが含まれています。結果のタイプは成功または失敗です。

1つのリストボックスに成功を表示する必要があります。別のリストボックスで失敗します。

私はこれを行うことができます。成功/失敗を保持するビューモデル内に2つの観測可能なコレクションを持つことによって、これを行うことができます。

public ObservableCollection<BatchImportResultMessageDto> ImportFailureMessageList { get; set; } // To hold the failure messages. 
public ObservableCollection<BatchImportResultMessageDto> ImportSuccessMessageList { get; set; } // To hold the sucess messages. 

しかし、私はそれを(新しい2つのコレクションなしで)フィルタリングできるように他の方法がありますか?

+0

はい - マークアップ拡張機能については、http://stackoverflow.com/questions/6461826/in-wpf-can-you-filter-a-collectionviewsource-with-code-behindを参照してください。 – Slugart

答えて

11

CollectionViewSourceを使用して、ビューモデルのプロパティにして、ImportMessageListコレクションの代わりにXAMLから直接バインドすることができます。 ImportMessageListコレクションをCollectionViewSourceのソースとして設定し、CollectionViewSourceでフィルタリングする述語を構成します。以下のような

何か:

private ICollectionView messageListView; 
public ICollectionView MessageListView 
{ 
    get { return this.messageListView; } 
    private set 
    { 
     if (value == this.messageListView) 
     { 
     return; 
     } 

     this.messageListView = value; 
     this.NotifyOfPropertyChange(() => this.MessageListView); 
    } 
} 

... 


this.MessageListView = CollectionViewSource.GetDefaultView(this.ImportMessageList); 
this.MessageListView.Filter = new Predicate<object>(this.FilterMessageList); 

... 

public bool FilterMessageList(object item) 
{ 
    // inspect item as message here, and return true 
    // for that object instance to include it, false otherwise 
    return true; 
} 
+0

CollectionViewSourceでフィルタリングする方法はありますか? – Relativity

+0

フィルタの例が追加されました – devdigital

+0

lisboxのために "MessageListView"を渡すことができますか? – Relativity

10

次の2つのCollectionViewSourceオブジェクトを作成し、それぞれにフィルタを設定することにより、これを行うことができます。

どのように結合VM(Source)からXAMLでCVSを作成するには:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Window.Resources> 
     <CollectionViewSource Source="{Binding}" x:Key="customerView"> 
      <CollectionViewSource.GroupDescriptions> 
       <PropertyGroupDescription PropertyName="Country" /> 
      </CollectionViewSource.GroupDescriptions> 
     </CollectionViewSource> 
    </Window.Resources> 
    <ListBox ItemSource="{Binding Source={StaticResource customerView}}" /> 
</Window> 

の背後にあるコードでCVSをフィルタリングするにはどのようにしている場合(あなたがあなたのモデルのプロパティを確認するためにリフレクションを使用することができますそれへの参照を作成する必要はありませんSource):後ろの(コード付き

<CollectionViewSource x:Key="MyCVS" 
           Source="{StaticResource CulturesProvider}" 
           Filter="MyCVS_Filter" /> 

)を

void MyCVS_Filter(object sender, FilterEventArgs e) 
{ 
    CultureInfo item = e.Item as CultureInfo; 
    if (item.IetfLanguageTag.StartsWith("en-")) 
    { 
     e.Accepted = true; 
    } 
    else 
    { 
     e.Accepted = false; 
    } 
} 
+1

コードビハインドは、MVVM-paternに違反します。 –

+9

コードビハインドにそのようなコードを入れることは、必ずしもmvvmパターンに違反するとは限りません。純粋にビュー関連(フィルタリングのみ)の場合は、コードビハインドを使用しても問題ありません。バインディングプロパティやxamlプロパティと同じくらいうまくいかないかもしれませんが、CollectionViewSourceはフィルタのプロパティをサポートしていません。 – bzuillsmith

関連する問題