我有一个班级人,该属于属性名称的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";
}
}
您可能应该在发布另一个问题之前阅读此内容。