2015-07-28 124 views
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事件。 –

相關問題