我在WPF中遇到了MVVM,我设置了file ID
和ObservableCollection
。 ICollectionView
设置为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
,就会重复{。}}。我如何设置集合以便我可以适当地设置过滤器?
答案 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);
}