gpt4 book ai didi

c# - 当列表中项目的属性更改时,ListCollectionView 上的 LiveFiltering 不会重新评估 Filter

转载 作者:太空宇宙 更新时间:2023-11-03 14:58:20 27 4
gpt4 key购买 nike

我有一个类 Person,它为属性名称实现了 INotifyPropertyChanged:

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”,我希望 View 会更新并且不再包含该项目。同样,将“Eric”更改为“Arnold”应该更新 View ,以便更改的项目成为 View 中的容器。

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*

我是否错过了启用某些东西来获得这种行为?我真的不想手动附加到每个 Person 实例的 PropertyChanged - 我仍然希望这就是 LiveFiltering 为我所做的。

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

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");
}
}
}

最佳答案

您的 View 和样本数据在哪里...?

下面的代码当然可以按预期工作。

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";
}
}

您可能应该阅读 this在你发布另一个问题之前。

关于c# - 当列表中项目的属性更改时,ListCollectionView 上的 LiveFiltering 不会重新评估 Filter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47681659/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com