2015-07-20 61 views
0

我试图在ObservableCollection<>上实现过滤。我目前的ObservableCollection<Payee>GridView上正常工作为ItemsSource。我添加了第二个ObservableCollection<Payee>,名为FilteredPayees,用作ItemsSource。出于某种原因,当我尝试过滤这些项目时,GridView显示为空白。ObservableCollection <>不能正确加载

这里是我使用的代码:

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设置发生更改,则无需重新加载 - 只需更改集合的过滤器即可。

+1

简短的回答:不长 - 答案:它取决于...是否有任何其他代码更改'_filteredPayees'? – derape

回答

2

您正在为FilteredPayees属性指定一个新对象,因此必须通知GridView属性FilteredPayees已更改。在FilteredPayees的设置器中应该有RaisePropertyChanged("FilteredPayees")或您的通知代码。

此外,GridView.ItemsSource的绑定模式不应该是BindingMode.OneTime

+0

我使用的是PrismMVVM,我的ViewModel继承了Prism.Mvvm.ViewModel类。我的属性如下所示:public ObservableCollection Payees { get {return _payees; } set {base.SetProperty(ref _payees,value); } }' 'public ObservableCollection FilteredPayees { {{_filteredPayees; } set {base.SetProperty(ref _filteredPayees,value); } }' –

+0

如果我使用'Payees'作为'ItemsSource',一切正常。即使我使用'FilteredPayees',只是将它设置为'= _payees;'而不是'_filteredPayees;'。 –

+0

我相信它确实与'INotifyPropertyChanged'有关,但所有使用'FilteredPayees'的设置与Payees'一样,并且该属性工作正常。感谢您的建议。 –

0

为了过滤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。优点是,您不需要两个属性,并且可以避免要绑定哪个集合的逻辑。

+0

不幸的是,我没有使用WPF。 ICollectionView在WinRT项目中不可用。 –

0
_filteredPayees = new ObservableCollection<Payee>(filtered); 

在这里,您创建了一个全新的对象,这不是ObservableCollection可以自动观察的事情。可能的解决方案是在此行之后再次在GridView上设置ItemsSource。

相关问题