2012-09-26 15 views
7

Ich habe kleine Demo von CollectionViewSource für WPF DataGrid in MVVM implementiert. Ich würde wirklich jede Hilfe schätzen, um die Implementierung zu überprüfen und zu kommentieren, ob dies der richtige Ansatz für die Verwendung von CollectionViewSource ist.CollectionViewSource MVVM-Implementierung für WPF DataGrid

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); 
    } 

Die XAML-Ansicht:

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

Die Hinter-Code:

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); 
    } 

Der Hyperlink_Click Handler ruft die UpdateDataGrid Methode der VM übergeben Sie Film-IDs getrennt Komma, die dann verwendet werden, Filtern Sie die MovieList-Auflistung mithilfe von Erweiterungsmethoden.

+0

Ihr Code ist ein wenig irreführend, bitte überprüfen Sie die Klassennamen. ViewModel, TagViewModel .. so können wir besser verstehen. – HichemSeeSharp

+0

Oh sorry @HichemC, hatte tatsächlich den Klassennamen beim Posten der Frage umbenannt. Vergessen, es im Code dahinter zu ändern. Gute Beobachtung aber. Danke, dass du meine Aufmerksamkeit auf mich gelenkt hast. – Lucifer

Antwort

17

Sie sollten keine neuen Instanzen der beobachtbaren Sammlung und der Sammlungsansicht erstellen. Weisen Sie der Filtereigenschaft in der Sammlungsansicht ein Prädikat zu, und rufen Sie jedes Mal auf, wenn Sie die Sammlung filtern möchten.

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

Sie können das Hinzufügen von Ressourcen überspringen, indem Sie direkt Folgendes tun: DataContext = new TagViewModel(); und Ihre Bindungen normal machen. aber ich empfehle dringend Dependency Injection.

2

Hier ist ein Beispiel eine Collection in der Reihenfolge der Instanziierung Mehr Filterung in einem Datenraster zu aktivieren: http://www.codeproject.com/Articles/442498/Multi-filtered-WPF-DataGrid-with-MVVM

Die Collection in der XAML Ansicht instanziiert wurde, aber auf eine Sammlung von Objekten in dem instanziierten gebunden ist Modell ansehen. Das Ansichtsmodell verwendet dann die CollectionViewSource, um die Daten im DataGrid zu filtern.

Was ist die richtige Ansatz, um eine CollectionViewSource instanziieren - das ist fraglich.