首页 > 解决方案 > 作为用户使用 IReactiveDerivedList 的正确方法在

问题描述

我有一个字符串的根列表ReactiveList<string>

private ReactiveList<string> Items { get; set; }

和一个派生列表

private IReactiveDerivedList<string> _FilteredItems;
public IReactiveDerivedList<string> FilteredItems{ get => _FilteredItems; set => this.RaiseAndSetIfChanged(ref _FilteredItems, value); }

我还有一个过滤器术语,它随着用户输入而改变TextBox

private string _FilterTerm;
public string FilterTerm { get => _FilterTerm; set => this.RaiseAndSetIfChanged(ref _FilterTerm, value); }

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

this.WhenAnyValue(This => This.FilterTerm).Where(filterTerm => filterTerm != null).Subscribe((filterTerm) =>
{
    FilteredItems = Items.CreateDerivedCollection(x => x, x => x.Contains(FilterTerm));
});

...我这样做是否正确,还是有更好的方法,因为这感觉有点像'我ReactiveList每次都可以创建一个新的,为什么要打扰IReactiveDerivedList'?


更新

我找到了以下示例,它几乎对我有用,https://janhannemann.wordpress.com/2016/10/18/reactiveui-goodies-ireactivederivedlist-filtering-2/,但它要求我添加一个IsFiltered属性我的 ViewModel,但在这种情况下,我没有使用 ViewModel,我只是使用string!

标签: c#reactive-programmingreactiveui

解决方案


正如我的评论中提到的。ReactiveUI 框架已弃用 ReactiveList 以支持 DynamicData https://reactiveui.net/docs/handbook/collections/

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

using System.Collections.ObjectModel;
using DynamicData;

public class FilteringClass
{
   private readonly ReadOnlyObservableCollection<string> _filteredItems;
   private readonly SourceList<string> _items = new SourceList<string>();
   private string _filterTerm;

   public FilteringClass(IEnumerable<string> items)
   {
      var filterTermChanged = this.WhenAnyValue(x => x.FilterTerm);
      _items.AddRange(items);
      _items.Connect()
         // This will update your output list whenever FilterTerm changes.
         .AutoRefreshOnObservable(_ => filterTermChanged)
         // This is similar to a Where() statement.
         .Filter(x => FilterTerm == null || x.Contains(FilterTerm))
         // SourceList is thread safe, this will make your output list only be updated on the main thread.
         .ObserveOn(RxApp.MainThreadScheduler)
         // This will make the FilteredItem's be updated with our data.
         .Bind(out _filteredItems)
         // This is a observable, so Subscribe to start the goodness.
         .Subscribe();

   }

   public string FilterTerm
   {
      get => _filterTerm;
      set => RaiseAndSetIfChanged(ref _filterTerm, value);
   }

   public ReadOnlyObservableCollection<string> FilteredItems => _filteredItems;
}

推荐阅读