C# WPF DataGrid的CollectionViewSource MVVM实现

C# WPF DataGrid的CollectionViewSource MVVM实现,c#,wpf,mvvm,datagrid,collectionviewsource,C#,Wpf,Mvvm,Datagrid,Collectionviewsource,我已经在MVVM中为WPF DataGrid实现了CollectionViewSource的小演示。如果您能帮助我验证实现并评论这是否是使用CollectionViewSource的正确方法,我将不胜感激 public class ViewModel : NotifyProperyChangedBase { private ObservableCollection<Movie> _movieList; public ObservableCollectio

我已经在MVVM中为WPF DataGrid实现了CollectionViewSource的小演示。如果您能帮助我验证实现并评论这是否是使用CollectionViewSource的正确方法,我将不胜感激

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

Hyperlink_Click处理程序调用VM的UpdateDataGrid方法,将逗号分隔的电影ID传递给它,然后使用扩展方法过滤电影列表集合。

您可以通过直接执行此操作跳过添加资源:
DataContext=new TagViewModel()并正常执行绑定。但是我强烈建议使用依赖注入。

您不应该创建可观察集合和集合视图的新实例。为collecion视图上的filter属性指定一个谓词,并在需要筛选集合时调用Refresh

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);
    }
}
公共类视图模型:notifyPropertyChangedBase
{       
字符串uri;
公共可观测集合电影列表{get;private set;}
公共集合视图电影视图{get;private set;}
公共视图模型(MoveList movieList)
{
MovieList=MovieList;
MovieView=GetMovieCollectionView(MovieList);
MovieView.Filter=OnFilterMovie;
}
public void UpdateDataGrid(字符串uri)
{     
this.uri=uri;
MovieView.Refresh();
}
bool onfilter电影(对象项)
{
var movie=(movie)项;
返回uri.Contains(movie.ID.ToString());
}
公共集合视图GetMovieCollectionView(可观察集合movList)
{
return(CollectionView)CollectionViewSource.GetDefaultView(movList);
}
}

以下是一个实例化CollectionViewSource以在DataGrid中启用多重筛选的示例:

CollectionViewSource已在XAML视图中实例化,但已绑定到视图模型中实例化的对象集合。然后,视图模型使用CollectionViewSource过滤DataGrid中的数据


至于实例化CollectionViewSource的正确方法是什么,这是有争议的。

您的代码有点误导,请验证类名。ViewModel,标记ViewModel。。所以我们可以更好地理解。哦,对不起@HichemC,实际上在发布问题时重命名了类名。忘记在代码后面更改它了。不过观察得不错。谢谢你引起我的注意。
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);
    }
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);
    }
}