当列表中项的属性发生更改时,ListCollectionView 上的实时筛选不会重新评估筛选器



我有一个班级人,该属于属性名称的InotifyPropertychangange:

public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string property)
    {
        Console.WriteLine("PropertyChanged: " + Name + ": " + property);
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }
    private string _name;
    public string Name
    {
        get => _name;
        set
        {
            if (_name == value)
                return;
            _name = value;
            OnPropertyChanged("Name");
        }
    }
}

我正在使用LiveFiltering使用ListCollectionView来显示ObservableCollection,被过滤以匹配一个名称以" A"开头的人:

var coll = new ObservableCollection<Person>();
ListCollectionView view = new ListCollectionView(coll)
{
    Filter = p => ((Person)p).Name[0]=='A',
    IsLiveFiltering = true,
    LiveFilteringProperties = { nameof(Person.Name) }
};

当项目添加到集合中时,它们会正确过滤。
这是一个问题:当更改人的名称时,过滤器未重新评估,这是我认为IsliveFiltering和LiveFilteringProperties首先是用的。因此,如果我将名称从" Anna"更改为" Elsa",我希望该视图会更新而不再包含该项目。同样,将" ERIC"更改为" Arnold"也应更新视图,以使更改的项目是视图中的容器。

var p1 = new Person { Name = "Anna" };
var p2 = new Person { Name = "Eric" };
coll.Add(p1); // view is updated automatically and contains Anna now
coll.Add(p2); // view is updated, but Eric is filtered out
view.Dump(); // shows only "Anna" (LINQPad - Dump)
p1.Name = "Elsa"; // change Anna to Elsa -> the instance p1 should be removed from view (not from collection)
p2.Name = "Arnold"; // change Eric to Arnold -> the instance p2 should now be in the view
//view.Refresh(); // uncommenting this line leads to the behaviour I actually expected from LiveFiltering to be handled automatically.
view.Dump(); // shows "Elsa", but we are filtering for A*

我是否想念启用某些东西来获得这种行为?我真的不想在每个人手动的情况下都依附于换人的财产 - 我仍然希望这是LiveFiltering对我所做的。

编辑:我在应用程序中以更大的模型遇到了这个问题,并提取了相关部分以重现LinqPad中的问题。这是完整的linqpad-script。它还需要使用条款:

using System.Collections.ObjectModel;
using System.Windows.Data;
using System.ComponentModel;

这是脚本

void Main()
{
    var coll = new ObservableCollection<Person>();
    ListCollectionView view = new ListCollectionView(coll)
    {
        IsLiveFiltering = true,
        LiveFilteringProperties = { nameof(Person.Name) },
        Filter = p => ((Person)p).Name[0] == 'A'
    };
    var p1 = new Person { Name = "Anna" };
    var p2 = new Person { Name = "Eric" };
    coll.Add(p1);
    coll.Add(p2);
    view.Dump();
    p1.Name = "Elsa";
    p2.Name = "Arnold";
    //view.Refresh();
    view.Dump();
    Debug.Assert(view.Cast<Person>().Single().Name == "Arnold", "Wrong item in view, expected Arnold");
}
public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string property)
    {
        Console.WriteLine("PropertyChanged: " + Name + ": " + property);
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }
    private string _name;
    public string Name
    {
        get => _name;
        set
        {
            if (_name == value)
                return;
            _name = value;
            OnPropertyChanged("Name");
        }
    }
}

您的视图和示例数据在哪里...?

以下代码肯定可以按预期工作。

XAML:

<ListBox x:Name="lb" DisplayMemberPath="Name" />
<Button Content="Filter" Click="Button_Click" />

示例代码:

public partial class MainWindow : Window
{
    Person _p = new Person() { Name = "Anna" };
    public MainWindow()
    {
        InitializeComponent();
        var coll = new ObservableCollection<Person>() { _p };
        ListCollectionView view = new ListCollectionView(coll)
        {
            Filter = p => ((Person)p).Name[0] == 'A',
            IsLiveFiltering = true,
            LiveFilteringProperties = { nameof(Person.Name) }
        };
        lb.ItemsSource = view;
    }
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        _p.Name = "Elsa";
    }
}

您可能应该在发布另一个问题之前阅读此内容。

相关内容

  • 没有找到相关文章

最新更新