MVVM中的ICollectionView和正确绑定以及ObservableCollection的过滤方法

时间:2017-07-24 15:32:21

标签: c# wpf mvvm datagrid

我在WPF中遇到了MVVM,我设置了file IDObservableCollectionICollectionView设置为ICollectionView的ItemsSource,模型类型为DataGrid

我为两个集合设置了getter和setter但是当我在Job上设置Filter而不是ICollectionView正在过滤Job时他们只是一遍又一遍地复制,让我相信他们的方式我收集设置是完全错误的。

以下是两个集合的获取/设置方式:

SearchString

现在我有一个绑定到public ObservableCollection<Job> AllJobs { get { foreach (var job in _allJobsList) _allJobs.Add(job); return _allJobs; } set { if (_allJobs == value) return; OnPropertyChanged("AllJobs"); } } public ICollectionView AllJobsView { get { _allJobsView = CollectionViewSource.GetDefaultView(AllJobs); return _allJobsView; } set { if (_allJobsView == value) { return; } _allJobsView = value; OnPropertyChanged("AllJobsView"); } } 的字符串SearchString。当文本发生变化时,我会执行以下操作:

TextBox.Text

现在首次加载页面时,public string SearchString { get => _searchString; set { if (_searchString == value) return; _searchString = value; FilterJobs(); OnPropertyChanged("SearchString"); } } private void FilterJobs() { AllJobsView.Filter = x => { var viewJob = x as Job; return viewJob != null && viewJob.Number.Contains(_searchString); }; } 中加载了正确的Jobs。但是,如果DataGrid确实包含Jobs,则只要用户输入Job.Number,就会重复{。}}。我如何设置集合以便我可以适当地设置过滤器?

1 个答案:

答案 0 :(得分:1)

问题出在ObservableCollection的getter中。每次你得到&#34;在集合中,您将再次将所有项目添加到集合中。

您的代码:

get
{
    foreach (var job in _allJobsList)
        _allJobs.Add(job);
    return _allJobs;
}

相反,它应该是:

get
{        
    return _allJobs;
}

你的ObservableCollection的setter也缺少&#34; setter&#34; (私有字段=值)代码:

set
{
    if (value != _allJobs)
    {
        _allJobs = value;
        OnPropertyChanged("AllJobs");
    }
}

您的财产AllJobs将是:

private ObservableCollection<Job> _allJobs;
public ObservableCollection<Job> AllJobs
{
    get
    {        
        return _allJobs;
    }
    set
    {
        if (value != _allJobs)
        {
            _allJobs = value;
            OnPropertyChanged("AllJobs");
        }
    }
}

集合的初始化应该在其他地方(而不是在属性的getter中),比如ViewModel的构造函数或/和在用户请求刷新集合后命令调用的方法中

例如,如果您的VieModel被称为MyViewModel并且您的List<Job>被称为_allJobsList,您可以像这样初始化您的集合:

public MyViewModel()
{
    //fill the _allJobsList first, getting from a database for example: _allJobsList = GetJobs();
    //and then create an observable collection from that list
    AllJobs = new ObservableCollection<Job>(_allJobsList);
}