2012-09-26 31 views
7

Tôi đã triển khai bản demo nhỏ của CollectionViewSource cho WPF DataGrid trong MVVM. Tôi thực sự đánh giá cao bất kỳ sự trợ giúp nào để xác minh việc thực hiện và nhận xét về việc đây có phải là cách tiếp cận đúng để sử dụng CollectionViewSource hay không.CollectionViewSource MVVM thực hiện cho 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); 
    } 

Các XAML Xem:

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

Bộ luật Đằng sau:

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

Việc xử lý Hyperlink_Click gọi phương thức UpdateDataGrid của VM đi qua nó dấu phẩy tách ID phim mà sau đó được sử dụng để lọc bộ sưu tập MovieList bằng các phương thức mở rộng.

+0

Mã của bạn hơi gây hiểu nhầm, vui lòng xác minh tên lớp. ViewModel, TagViewModel .. để chúng tôi có thể hiểu rõ hơn. – HichemSeeSharp

+0

Xin lỗi @HichemC, thực sự đã đổi tên tên lớp trong khi đăng câu hỏi. Quên để thay đổi nó trong mã phía sau. Quan sát tốt mặc dù. Cảm ơn vì đã thu hút sự chú ý của tôi. – Lucifer

Trả lời

17

Bạn không nên tạo các phiên bản mới của bộ sưu tập có thể quan sát và chế độ xem bộ sưu tập. Gán một biến vị ngữ cho thuộc tính bộ lọc trên khung nhìn collecion và gọi Refresh bất cứ khi nào bạn muốn lọc bộ sưu tập.

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

Bạn có thể bỏ qua việc thêm tài nguyên bằng cách thực hiện việc này trực tiếp: DataContext = new TagViewModel(); và thực hiện các liên kết của bạn bình thường. nhưng tôi khuyên bạn nên sử dụng Dependency Injection.

2

Dưới đây là một ví dụ về instantiating một CollectionViewSource để kích hoạt tính năng đa lọc trong một DataGrid: http://www.codeproject.com/Articles/442498/Multi-filtered-WPF-DataGrid-with-MVVM

Các CollectionViewSource được khởi tạo trong giao diện XAML nhưng được ràng buộc với một bộ sưu tập của các đối tượng thuyết minh trong các xem mô hình. Mô hình khung nhìn sau đó sử dụng CollectionViewSource để lọc dữ liệu trong DataGrid.

Cách tiếp cận đúng để khởi tạo CollectionViewSource - đó là điều gây tranh cãi.

Các vấn đề liên quan