Windows Phone 8.1 Universal上的ObservableCollection过滤

时间:2015-07-28 11:25:25

标签: c# windows-runtime windows-phone-8.1 observablecollection

我正在编写Windows Phone 8.1通用应用程序,主要应用程序控件是Pivot,几个枢轴项。在透视项中是包含TestItems的ListView。我想通过IsRead属性过滤一个列表中的项目。是否可以在不保留2个集合的情况下过滤主集合?如果我知道,CollectionViewSource不支持在通用应用上过滤排序。但保持(并同步变化)两个集合并不是一个好主意。

修改: 我使用了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?
    }

    // ...
}

3 个答案:

答案 0 :(得分:0)

您可以使用Linq;

在你的情况下:

RFC 2445

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

答案 1 :(得分: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);
}

我还没有测试过这段代码。

答案 2 :(得分:0)

您只需要一个ObservableCollection包含初始对象和另一个属性(让我们说ItemsFiltered),并使用get方法在过滤后返回结果。在构造函数中,您可以订阅observable集合的CollectionChanged事件,以便为OnPropertyChanged属性引发ItemsFiltered事件。更改过滤器状态时引发相同的事件。这是一个简单的例子:

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也会更新。