为什么带有复选框的列表框在过滤更改时会忘记项目的状态?

时间:2019-12-03 16:36:54

标签: c# wpf

用户会在ListBox上选中/取消选中项目的复选框。

我添加了CollectionViewSource以允许过滤列表,因为它可以包含数百个项目。

如果我应用了过滤器,请选中/取消选中某个项目并删除过滤器,那么它将“忘记”了更改。因此,如果我检查了第4项,则当我删除过滤器时,第4项将被取消选中。 如果我确实进行更改而没有过滤,则可以检索它们。

我现在知道我在做什么错,但是我猜是显示的集合是原始源(SourceCollection)的副本,而我实际上并没有修改该列表。 因此,当过滤器发生更改时,CollectionViewSource将创建源集合的新集合基础。

这是我的代码背后:

ObservableCollection<Machine> data = new ObservableCollection<Machine>(db.getmachines());
lbItems.ItemsSource = data;
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lbItems.ItemsSource);
view.Filter = UserFilter;

我的XAML:

<ListBox Name="lbItems">
    <ListBox.Resources>
        <DataTemplate>
            <StackPanel>
                <CheckBox IsChecked="{Binding Selected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                <TextBlock Text="{Binding Name}" />
            </Grid>
        </DataTemplate>
    </ListBox.Resources>
</ListBox>

我是在做错什么,还是CollectionViewSource的行为? 我有什么解决方案? 抱歉,如果我错过了什么,请告诉我,我将更新问题。

2 个答案:

答案 0 :(得分:1)

您应该将ItemsSource设置为CollectionView而不是基础数据。您还应该从原始集合中创建CollectionView,而不是从ItemsSource属性中创建,这不会反映对原始集合所做的更改。

更改原始图片

lbItems.ItemsSource = data;
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lbItems.ItemsSource);
view.Filter = UserFilter;

进入

CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(data);
lbItems.ItemsSource = view;
view.Filter = UserFilter;

因为您绑定到Selected属性,所以状态将保持不变,而您拥有的Filter属性。

答案 1 :(得分:1)

首先,您应该绑定ICollectionView本身,而不是数据。

// data and view are stored somewhere locally
data = new ObservableCollection<Machine>(db.getmachines());
view = CollectionViewSource.GetDefaultView(data);
view.Filter = UserFilter;
lbItems.ItemsSource = view;

当您需要访问您的值并查看是否已检查它们时-使用数据值。如果您只需要访问过滤的集合,则应该像这样投射视图:

var filteredCollection = view.Cast<Machine>();