C# 当用户在中键入筛选项时使用IReactiveDerivedList的正确方法

C# 当用户在中键入筛选项时使用IReactiveDerivedList的正确方法,c#,reactive-programming,reactiveui,C#,Reactive Programming,Reactiveui,我在ReactiveList 最后,我在构造函数中使用以下内容,每当FilterTerm发生更改时,它都会重新创建派生列表 this.WhenAnyValue(This => This.FilterTerm).Where(filterTerm => filterTerm != null).Subscribe((filterTerm) => { FilteredItems = Items.CreateDerivedCollection(x => x, x =>

我在
ReactiveList

最后,我在构造函数中使用以下内容,每当
FilterTerm
发生更改时,它都会重新创建派生列表

this.WhenAnyValue(This => This.FilterTerm).Where(filterTerm => filterTerm != null).Subscribe((filterTerm) =>
{
    FilteredItems = Items.CreateDerivedCollection(x => x, x => x.Contains(FilterTerm));
});
。。。我这样做是否正确,或者是否有更好的方法,因为这感觉有点像‘每次我都可以创建一个新的
反应列表
,为什么还要麻烦使用
IReactiveDerivedList


更新


我发现下面的示例几乎适用于我,但它要求我向我的ViewModel添加一个
IsFiltered
属性,但在这种情况下,我没有使用ViewModel,我只是使用
字符串

正如我在评论中提到的。ReactiveUI框架不赞成使用ReactiveList,而赞成使用DynamicData

如果要在DynamicData中实现这一点,请执行以下操作:

使用System.Collections.ObjectModel;
使用动态CDATA;
公共类过滤器类
{
私有只读只读可观察集合_filteredItems;
私有只读源列表_items=new SourceList();
私有字符串_filterTerm;
公共过滤器类(IEnumerable items)
{
var filterTermChanged=this.WhenAnyValue(x=>x.FilterTerm);
_items.AddRange(items);
_items.Connect()
//这将在FilterTerm发生更改时更新输出列表。
.AutoRefreshonoObservable(=>FiltermChanged)
//这类似于Where()语句。
.Filter(x=>FilterTerm==null | | x.Contains(FilterTerm))
//SourceList是线程安全的,这将使输出列表仅在主线程上更新。
.ObserveOn(RxApp.MainThreadScheduler)
//这将使用我们的数据更新FilteredItem。
.Bind(out\u filteredItems)
//这是一个可观察的,所以请订阅开始善良。
.Subscribe();
}
公共字符串筛选器项
{
get=>\u filterTerm;
set=>RaiseAndSetIfChanged(ref\u filterTerm,value);
}
public ReadOnlyObservableCollection FilteredItems=>\u FilteredItems;
}

我们不推荐使用ReactiveList/IReactiveDerivedList,而支持使用DynamicData,有关详细信息,请参阅。处理事情的方法稍有不同,但功能更强大/更灵活。您也可以使用ObservableCollection或ObservableCollectionExtended,如果您使用它们,请注意它们不是线程安全的,您可以使用
ToObservableChangeSet()
方法而不是
Connect()
SourceList
意味着在你的课堂上不能是私人的。谢谢你的回答。我确实看过dynamicata,但当时我“很匆忙”,认为学习曲线可能有点陡峭。我现在明白了这是值得的:0)我刚刚尝试了这个,但是在
.AutoRefresh(x=>x.FilterTerm)
上出现了编译错误。。。“'string'不包含'FilterTerm'的定义,并且找不到可访问的扩展方法'FilterTerm'接受'string'类型的第一个参数”。。。这是有意义的,因为
x
是一个
字符串
!我一直在想如何在
AutoRefresh(…)
表达式中引用
FilteringClass.FilterTerm
?我修改了答案。抱歉,AutoRefresh()适用于集合中存储的对象的属性,否则您必须使用AutoRefreshOnObservable()。因此,AutoRefreshOnObservable()的工作方式是它是一个Lambda,参数是项中的单个项,并且您返回一个可观察项,当发出信号时将导致重新计算该项。在这种情况下,由于希望重新评估所有项,因此忽略该参数,只需将可观察项返回到FilterTerm更改事件。
private IReactiveDerivedList<string> _FilteredItems;
public IReactiveDerivedList<string> FilteredItems{ get => _FilteredItems; set => this.RaiseAndSetIfChanged(ref _FilteredItems, value); }
private string _FilterTerm;
public string FilterTerm { get => _FilterTerm; set => this.RaiseAndSetIfChanged(ref _FilterTerm, value); }
this.WhenAnyValue(This => This.FilterTerm).Where(filterTerm => filterTerm != null).Subscribe((filterTerm) =>
{
    FilteredItems = Items.CreateDerivedCollection(x => x, x => x.Contains(FilterTerm));
});