2012-09-26 59 views
7

MVVMのWPF DataGrid用のCollectionViewSourceの小さなデモを実装しました。実装を検証し、これがCollectionViewSourceを使用する正しいアプローチであるかどうかについてコメントするための助けに本当に感謝します。CollectionViewSource WPF DataGrid用MVVM実装

public class ViewModel : NotifyProperyChangedBase 
{  
    private ObservableCollection<Movie> _movieList; 
    public ObservableCollection<Movie> MovieList 
    { 
     get { return _movieList; } 
     set 
     { 
      if (this.CheckPropertyChanged<ObservableCollection<Movie>>("MovieList", ref _movieList, ref value)) 
       this.DisplayNameChanged(); 
     } 
    } 

    private CollectionView _movieView; 
    public CollectionView MovieView 
    { 
     get { return _movieView; } 
     set 
     { 
      if (this.CheckPropertyChanged<CollectionView>("MovieView", ref _movieView, ref value)) 
       this.DisplayNameChanged(); 
     } 
    } 

    public ViewModel() 
    { 
      MovieView = GetMovieCollectionView(MovieList); 
    } 

    private void DisplayNameChanged() 
    { 
     this.FirePropertyChanged("DisplayName"); 
    } 

    public void UpdateDataGrid(string uri) 
    {    
     MovieView = GetMovieCollectionView(new ObservableCollection<Movie>(MovieList.Where(mov => uri.Contains(mov.ID.ToString())).ToList<Movie>())); 
    } 

    public CollectionView GetMovieCollectionView(ObservableCollection<Movie> movList) 
    { 
     return (CollectionView)CollectionViewSource.GetDefaultView(movList); 
    } 

XAMLビュー:

<Window.Resources> 
    <CollectionViewSource x:Key="MovieCollection" Source="{Binding MovieList}"> 
    </CollectionViewSource> 
    </Window.Resources> 
    <DataGrid Name="MyDG" 
      ItemsSource="{Binding MovieView}" 
      AutoGenerateColumns="True" /> 

コードの後ろに:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     this.Resources.Add("TagVM", new TagViewModel()); 
     this.DataContext = this.Resources["TagVM"]; 
    } 

    private void Hyperlink_Click(object sender, RoutedEventArgs e) 
    { 
     string uri = ((Hyperlink)sender).NavigateUri.ToString(); 
     ((ViewModel)this.DataContext).UpdateDataGrid(uri); 
    } 

Hyperlink_Clickハンドラは、それが、その後に使用されている動画IDをカンマ区切り渡すVMのUpdateDataGridメソッドを呼び出します拡張メソッドを使用してMovieListコレクションをフィルタリングします。

+0

コードが誤解を招く場合があります。クラス名を確認してください。 ViewModel、TagViewModel ..私たちはもっと理解することができます。 – HichemSeeSharp

+0

ああ申し訳ありません@HichemC、実際に質問を投稿している間にクラス名を変更しました。コードの背後でそれを変更するのを忘れました。しかし、良い観察。私の注意を引くことに感謝します。 – Lucifer

答えて

17

observableコレクションとコレクションビューの新しいインスタンスを作成しないでください。コレクションビューの「フィルター」プロパティーに述部を割り当て、コレクションをフィルターに掛けるたびに「リフレッシュ」を呼び出します。ここ

public class ViewModel : NotifyProperyChangedBase 
{  
    string uri; 

    public ObservableCollection<Movie> MovieList { get; private set; } 

    public CollectionView MovieView { get; private set; } 

    public ViewModel(MoveList movieList) 
    { 
     MovieList = movieList; 
     MovieView = GetMovieCollectionView(MovieList); 
     MovieView.Filter = OnFilterMovie; 
    } 

    public void UpdateDataGrid(string uri) 
    {  
     this.uri = uri; 
     MovieView.Refresh(); 
    } 

    bool OnFilterMovie(object item) 
    { 
     var movie = (Movie)item; 
     return uri.Contains(movie.ID.ToString()); 
    } 

    public CollectionView GetMovieCollectionView(ObservableCollection<Movie> movList) 
    { 
     return (CollectionView)CollectionViewSource.GetDefaultView(movList); 
    } 
} 
0

リソースを直接追加することをスキップすることができます:DataContext = new TagViewModel();とバインディングを正常に実行してください。依存性注入を使用することを強くお勧めします。

2

は、データグリッドにおけるマルチフィルタリングを可能にするためにCollectionViewSourceをインスタンス化の例である:http://www.codeproject.com/Articles/442498/Multi-filtered-WPF-DataGrid-with-MVVM

CollectionViewSourceはXAMLビューでインスタンス化されたが、でインスタンス化オブジェクトのコレクションにバインドされていますビューモデル。次に、ビューモデルはCollectionViewSourceを使用してDataGridのデータをフィルタリングします。

については、というアプローチで、CollectionViewSourceをインスタンス化するアプローチが議論の対象となります。

関連する問題