1

我正在写windows phone 8.1通用应用程序,并且主要应用程序控件是Pivot,只有少量数据。在透视项目中是包含TestItems的ListViews。我想通过IsRead属性筛选一个列表中的项目。是否有可能过滤主要收藏而不保留2个收藏?如果我知道的话,CollectionViewSource不支持在通用应用上过滤排序。但保持(和同步更改)两个集合看起来不是个好主意。Windows Phone 8.1上的ObservableCollection过滤通用

编辑: 我已经使用了ObservableCollection,因为项目列表可能会在后台更新。可能从原始问题中不清楚。

class TestItem : ModelBase 
{ 
    private bool isRead; 
    public bool IsRead 
    { 
     get { return isRead; } 
     set 
     { 
      isRead = value; 
      NotifyPropertyChanged(); 
     } 
    } 

    private string name; 
    public string Name 
    { 
     get { return name; } 
     set 
     { 
      name = value; 
      NotifyPropertyChanged(); 
     } 
    } 
} 

class MainViewModel : INotifyPropertyChanged 
{ 
    public MainViewModel() 
    { 
     Items = new ObservableCollection<TestItem>(); 
    } 

    public ObservableCollection<TestItem> Items { get; private set; } 
    public ObservableCollection<TestItem> ItemsRead { get; private set; } // key point 

    private void RefreshItems() 
    { 
     // data manipulation - on both collections? 
    } 

    // ... 
} 

回答

0

您可以使用Linq;

你的情况:

using System.Linq; 

class MainViewModel : INotifyPropertyChanged 
{ 
    public MainViewModel() 
    { 
     Items = new ObservableCollection<TestItem>(); 
    } 

    public ObservableCollection<TestItem> Items { get; private set; } 
    //public ObservableCollection<TestItem> ItemsRead { get; private set; } // key point 
    public IEnumerable<TestItem> ItemsRead 
    { 
     get 
     { 
      IEnumerable<TestItem> itemsRead = from item in Items 
              where item.IsRead 
              select item; 
      return itemsRead; 
     } 
    } 


    private void RefreshItems() 
    { 
     // data manipulation - on both collections? 
    } 

    // ... 
} 

请检查语法,它可以包含一些错误。 您可以使用第一个集合进行操作,第二个集合将自动更新。

+0

但问题是,该视图不会通知有关更改。 – Fanda

0

您可以在XAML定义CollectionViewSource

<Grid.Resources> 
    <CollectionViewSource x:Name="MyCollectionViewSource"/> 
</Grid.Resources> 

然后设置它的来源是这样的:

//Global variable 
MainViewModel vm; 

//Constructor 
public MyPage(){ 
    //Other code 
    vm = new MainViewModel(); 
    vm.Items.CollectionChanged += Items_CollectionChanged; 
    UpdateViewSource(); 
} 

private void Items_CollectionChanged(object sender, CollectionChangedEventArgs e){ 
    UpdateViewSource(); 
} 

private void UpdateViewSource(){ 
    MyCollectionViewSource.Source = vm.Items.Where(x => x.IsRead); 
} 

我还没有测试此代码。

0

您只需要一个ObservableCollection包含初始对象和另一个属性(假设ItemsFiltered),而get方法在过滤后返回结果。在构造函数中,您可以订阅可观察集合的CollectionChanged事件,以提高ItemsFiltered属性的OnPropertyChanged事件。当过滤器状态发生变化时,您将引发相同的事件。这是一个简单的例子:

public MainViewModel() 
{ 
    _initialItems.CollectionChanged += (sender, e) => OnPropertyChanged("Items"); 
} 

private ObservableCollection<TestItem> _initialItems = new ObservableCollection<TestItem>(); 

public List<TestItem> Items 
{ 
    get 
    { 
     if (IsReadFilter) 
     { 
      return _initialItems.Where(i => i.IsRead).ToList(); 
     } 

     return _initialItems; 
    } 
} 

private bool _isReadFilter; 
public bool IsReadFilter 
{ 
    get { return _isReadFilter; } 
    set 
    { 
     if (_isReadFilter != value) 
     { 
      _isReadFilter = value; 
      OnPropertyChanged("IsReadFilter"); 
      OnPropertyChanged("Items"); 
     } 
    } 
} 

基本上,这个想法是,每一次IsReadFilter值发生改变时,UI得到通知,该Items属性更改,并调用其get方法来获得新的价值和更新。每当可观察集合从其他地方更改时,Items也会更新。

+0

我编辑了我的问题,我确实需要ObservableCollection。对不起,我的问题并不清楚。 – Fanda

+0

好的,我稍微修改了我的答案。只能将_initialItems集合替换为可观察集合并订阅其CollectionChanged事件。 –

相关问题