を変更したときにフィルターを再評価しません。LiveFilteringは、リスト内のアイテムのプロパティは、私は、プロパティ名のためにINotifyPropertyChangedのを実装するクラスの人を、持っている
var coll = new ObservableCollection<Person>();
ListCollectionView view = new ListCollectionView(coll)
{
Filter = p => ((Person)p).Name[0]=='A',
IsLiveFiltering = true,
LiveFilteringProperties = { nameof(Person.Name) }
};
アイテムがコレクションに追加されている場合、それらが正しくフィルタされています。名前が「A」で始まる人だけを一致させるためのフィルタのObservableCollectionを、表示します
問題: Personの名前が変更されたとき、最初に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*
この現象が発生するのを忘れましたか? 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");
}
}
}
問題に再現するために使用した完全なLinqPadスクリプトを追加しました。うまくいけば、間違いが見えるようになります。 – Michael
ライブフィルタリングは、サンプルコードが明らかに示すように、実際にイベントのサブスクライバが存在する場合、WPFアプリケーションのコンテキストで確実に機能します。 Linqpadで動作しない場合、LinqPadに問題があり、ListCollectionViewには問題があります。 – mm8
もちろん、それは絶対に真です。私が "バグ"を分離してLinqPadで再現しようとしたとき、私はLinqPadがもちろんコレクションビューのイベントに登録していないことに気付かなかった。投稿したコードはもちろん動作し、LiveFiltering機能から期待した動作です。 私のアプリで最初に経験したバグは、別の場所に導入されました。すべてが期待どおりに機能するので(私がうんざりしない限り)、私はこれに答えてマークします。 – Michael