使用ObservableCollection<T>和动态过滤器的Silverlight ListBox

4

假设我有这个类:

public class MyData
{
    public bool IsActive{get;set;}
    public String Data1 {get;set;}
    public String Data2 {get;set;}
}

并且一个

ObservableCollection<MyData> data = new ObservableCollection<MyData>;
ListBox.ItemsSource = data;

将项添加到ObservableCollection中的操作按预期工作;但是,我想确保我的ListBox仅显示设置为“true”的IsActive项--我无法使用Linq查询来设置ItemsSource,因为那样就不是ObservableCollection了,它是IEnumerable类型,并不会向ListBox发送任何更新通知。

2个回答

9
你的答案是CollectionViewSource。不要绑定到列表,而是绑定到CollectionViewSource实例。
下面是一个稍微退化的示例(我不确定你是否使用ViewModels、Locators等来解决数据和列表)。假设在你的标记中,你已经声明了一个CollectionViewSource作为资源:
<phone:PhoneApplicationPage.Resources>
    <CollectionViewSource x:Key="src"/>
</phone:PhoneApplicationPage.Resources>

然后您的列表绑定看起来像这样:
<ListBox x:Name="MyListBox" ItemsSource="{Binding Source={StaticResource src}}">

最后,在代码中,您可以将列表和集合视图源代码结合起来:
        var collectionView = this.Resources["src"] as CollectionViewSource;
        // Check for null, etc.
        collectionView.Source = observableCollectionThatIAmBindingTo;
        collectionView.View.Filter=new Predicate<Object>(o => ((ItemType)o).IsActive );

此外,您可能希望查看Bea Stollnitz有关该主题的文章:

http://bea.stollnitz.com/blog/?p=31

http://bea.stollnitz.com/blog/?p=392


这个编译了,但是没有显示我任何的项目(我验证了集合中既有 IsActive=True 也有 IsActive=False)。您有什么想尝试的吗? - Nate
似乎没有View.Filter部分也能正常工作。虽然谓词似乎没问题... - Nate

-1

更简单的方法是在 XAML 中使用 Visibility

假设你的 ListBoxItemTemplate 使用 StackPanel 来保存数据,而在这种情况下,你有两个 TextBlock 在这个 StackPanel 中(一个用于 Data1,一个用于 Data2)。

因此,你应该将这个 StackPanelVisibilityIsActive 绑定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接