【问题标题】:CollectionViewSource MVVM Implementation for WPF DataGridWPF DataGrid 的 CollectionViewSource MVVM 实现
【发布时间】:2012-09-17 22:33:35
【问题描述】:

我已经在 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);
    }

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 处理程序调用 VM 的 UpdateDataGrid 方法,将逗号分隔的电影 ID 传递给它,然后使用扩展方法过滤 MovieList 集合。

【问题讨论】:

  • 您的代码有点误导,请验证类名。 ViewModel,TagViewModel..这样我们可以更好的理解。
  • 对不起@HichemC,实际上在发布问题时重命名了班级名称。忘记在后面的代码中更改它。不过观察力不错。感谢您引起我的注意。

标签: c# wpf mvvm datagrid collectionviewsource


【解决方案1】:

您不应创建可观察集合和集合视图的新实例。为集合视图上的过滤器属性分配一个谓词,并在您想要过滤集合时调用 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);
    }
}
【解决方案2】:

这是一个实例化 CollectionViewSource 以在 DataGrid 中启用多重过滤的示例:http://www.codeproject.com/Articles/442498/Multi-filtered-WPF-DataGrid-with-MVVM

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

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

【讨论】:

    【解决方案3】:

    您可以直接通过以下方式跳过添加资源:DataContext = new TagViewModel(); 并正常进行绑定。但我强烈推荐使用依赖注入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-03
      • 1970-01-01
      • 1970-01-01
      • 2021-07-17
      • 1970-01-01
      相关资源
      最近更新 更多