ObservableCollection<>;加载不正确
本文关键字:加载 不正确 gt lt ObservableCollection | 更新日期: 2023-09-27 18:03:34
我正在尝试在ObservableCollection<>
上实现过滤。我当前的ObservableCollection<Payee>
可以像GridView
上的ItemsSource
一样正常工作。我添加了第二个ObservableCollection<Payee>
,称为FilteredPayees
,用作ItemsSource
。出于某种原因,当我尝试筛选项目时,GridView
显示为空白。
这是我正在使用的代码:
private void FilterPayees()
{
if (!_settings.ShowInactivePayees)
{
var filtered = _payees.Where(p => p.IsOpen == true);
_filteredPayees = new ObservableCollection<Payee>(filtered);
}
else
{
_filteredPayees = _payees;
}
this.FilteredPayees = _filteredPayees;
}
基本上,如果ShowInactivePayees
设置被关闭,它应该过滤掉不活动的收款人。如果它处于启用状态,那么只需使用完整的_payees
集合。奇怪的是,如果我把最后一行改为:
this.FilteredPayees = _payees;
然后GridView
将显示所有收款人,就像打开"显示非活动收款人"设置时一样。我设置了断点,_filteredPayees
集合中有35个项目(不过滤时为65个(。它似乎不是任何类型的"未设置为对象实例的对象"或类似的东西。
this.FilteredPayees = _payees;
可以,但是
_filteredPayees = _payees;
this.FilteredPayees = _filteredPayees;
不会吗?
编辑
我现在可以通过去掉FilteredPayees
属性来让它发挥作用。我只是在OnNavigatedTo()
事件处理程序中过滤原始的Payees
集合,它与我调用FilteredPayees()
的位置完全相同。
// load payees
var payees = await _payeesRepository.LoadAllAsync();
if (!_settings.ShowInactivePayees)
{
payees = payees.Where(p => p.IsOpen);
}
payees = payees.OrderBy(p => p.CompanyName);
this.Payees = new ObservableCollection<Payee>(payees);
我添加的唯一部分是if (!_settings.ShowInactivePayees) ...
块。我使用FilteredPayees
属性的理由是,我可以在Payees
属性中加载完整的集合,如果ShowInactivePayees
设置发生更改,则不需要重新加载-只需更改集合的筛选器即可。
您正在为FilteredPayees
属性分配一个新对象,因此必须通知GridView
属性FilteredPayees
已更改。FilteredPayees
的设置器中应该有RaisePropertyChanged("FilteredPayees")
或您的通知代码。
此外,GridView.ItemsSource
的绑定模式不应该是BindingMode.OneTime
。
对于在WPF中筛选集合,使用ICollectionView
可能更容易。例如:
public class Foo
{
private List<Payee> _payees;
private ICollectionView _filteredPayees;
public ICollectionView FilteredPayees
{
get { return _filteredPayees; }
}
public Foo()
{
_payees = GetPayees();
_filteredPayees = CollectionViewSource.GetDefaultView(_payees);
_filteredPayees.Filter = FilterPayees;
}
private bool FilterPayees(object item)
{
var payee = item as Payee;
if (payee == null)
{
return false;
}
if (_settings.ShowInactivePayees)
{
return true;
}
return payee.IsOpen;
}
}
您可以像绑定任何其他属性一样绑定属性FilteredPayees
。优点是,您不需要两个属性,并且可以避免要绑定哪个集合的逻辑。
_filteredPayees = new ObservableCollection<Payee>(filtered);
在这里,您创建了一个全新的对象,而这不是ObservableCollection可以自动观察到的。可能的解决方案是在此行之后再次在GridView上设置ItemsSource。